Core concepts

Screen and Island

A SwiftUI or Compose view only exists inside a native host. Screen is a whole screen of them; Island is one patch of native layout inside React Native. Outside either, a native component renders nothing — in development, useHostGuard warns which one it was.

Screen

The full-bleed host a native screen starts with. Its children lay out in a column filling the screen, natively all the way down.

app/settings.tsx
export default function Settings() {
  return (
    <Screen>
      <Form>
        <Form.Section title="Notifications">
          <Switch label="Order updates" onValueChange={setUpdates} value={updates} />
        </Form.Section>
      </Form>
    </Screen>
  )
}

Island

A native host inside React Native layout: a scroll view of React Native sections with a native control here and there. It sizes its height to its native content, and takes its width from the parent.

Some native views have no height of their own — List, Form on iOS, Pager, ScrollView. In an island they need matchContents={false} and an explicit height, or they show nothing (Compose throws on an infinite height).

tsx
<Island matchContents={false} style={{height: 240}}>
  <List>
    <ListItem title="Account" />
    <ListItem title="Privacy" />
  </List>
</Island>

Keep a page to a few islands. Dozens of Compose hosts in one frame stall Android’s main thread; a long list of rows belongs in a list, not in a column of islands.

React Native inside native

RnView carries one React Native view back into a native layout. Native text belongs inside the host as Text; a bare string under RnView cannot cross the boundary.

tsx
<VStack spacing="s8">
  <Text variant="footnote">Three React Native boxes:</Text>
  <RnView>
    <Box flexDirection="row" gap="s8">{swatches}</Box>
  </RnView>
</VStack>

An island whose content contains an RnView needs matchContents={false} and a height, or the two measurements chase each other.

Lists

Rows areUse
Native views, in a native screenList with ListItems, in a Screen.
React Native content, many of them — hosts in them includedRnFlatList or RnSectionList: React Native’s own virtualized lists, cells in normal flow, so a hosted view stays where the layout put it. Bring your own recycling list for plain data rows if you need one; recycled cells move, which a host does not survive.
A handful that should not scrollA VStack (native) or a Box (React Native).