Getting started

Native UI for Expo

kara is a design system for Expo whose components render real SwiftUI and Jetpack Compose views — a Switch is a SwiftUI Toggle on iOS and a Material Switch on Android — styled through one token-typed sx surface. Platform colours and the platform’s typeface by default; yours through the theme.

A first screen

Mount KaraProvider once at the root. A screen of native views starts with Screen; everything inside lays out natively and takes sx props resolved from the theme’s tokens.

App.tsx
import {Button, KaraProvider, Screen, Text, VStack} from '@hzblj/kara-ui'

export const App = () => (
  <KaraProvider>
    <Screen>
      <VStack p="s16" spacing="s12" wide>
        <Text variant="headingS">Hello</Text>
        <Button label="Continue" onPress={next} wide />
      </VStack>
    </Screen>
  </KaraProvider>
)

kara needs a development build — its views are native code, so Expo Go cannot run them. iOS and Android, Expo SDK 57. There is no web target.

Two tiers

Native views live in a native host. Most of kara is that native tier; the rest is a React Native tier of plain React Native views with the same sx props, for layout, long lists and the pieces a native host does not suit.

TierRendersWhere it goesExamples
NativeSwiftUI on iOS, Jetpack Compose on AndroidInside a Screen or an IslandButton, Switch, Text, VStack, List
React NativeReact Native views — some backed by kara’s own UIKit and Compose viewsAnywhereBox, RnText, Pressable, Sheet, ContextMenu, GlassView

A page that is mostly React Native drops native views in where it needs them, each in an Island:

checkout.tsx
import {Box, Button, Island, RnScrollView, RnText} from '@hzblj/kara-ui'

export const Checkout = () => (
  <RnScrollView content={{gap: 's24', p: 's20'}}>
    <RnText variant="headingS">Checkout</RnText>
    <Box bg="surface.primary" borderRadius="large" p="s16">
      <RnText color="content.secondary">2 items · €129</RnText>
    </Box>
    <Island>
      <Button label="Pay €129" onPress={pay} wide />
    </Island>
  </RnScrollView>
)

Next