Getting Started
Three steps: install, wrap your app in UIProvider, then import components. Skipping step 2 is the single most common way to break orn-ui — every hook and every component reads theme, icons and labels from it.
1. Install
Either the whole package, or just the components you need via the CLI (no npm dependency for the second option — see each component page for its own command).
pnpm add orn-ui/npx orn-ui add buttonCompatibility
Verified on Expo SDK 54, 55, 56 and 57 — every one of them, not just the newest. Each SDK gets its own sandbox with that release's exact react-native and react, and both the type check and the full test suite run against it in CI. Bare React Native works the same way: nothing in the library imports Expo.
| Expo SDK | react-native | react |
|---|---|---|
| 54 | 0.81.5 | 19.1.0 |
| 55 | 0.83.10 | 19.2.0 |
| 56 | 0.85.3 | 19.2.3 |
| 57 | 0.86.2 | 19.2.3 |
Declared as peerDependencies: react-native >=0.81.0 and react >=19.1.0. react-native-safe-area-context >=5.4.0 is optional — only orn-ui/safe-area imports it.
2. Wrap your app in UIProvider
UIProvider is the single entry point of the library. It resolves the active theme (system or manual override) and injects icons, safe-area insets and default labels to the whole tree. Mount it once, above your navigator — root of App.tsx is the usual place.
import { UIProvider } from 'orn-ui';
export default function App() {
return (
<UIProvider>
{/* your navigator / screens go here */}
</UIProvider>
);
}UIProvider props
| Name | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | Your app — mounted once, above the navigator. |
theme? | ThemePair | defaultTheme | Light/dark pair. Build one with createTheme(). |
defaultMode? | 'system' | 'light' | 'dark' | 'system' | Initial mode, uncontrolled. |
mode? | 'system' | 'light' | 'dark' | — | Controlled mode — pass with onModeChange to manage it yourself. |
onModeChange? | (mode: ThemeMode) => void | — | Called on toggle when mode is controlled. |
icons? | IconRenderer | renderDefaultIcon | Icon renderer. Defaults to the zero-dep glyphs bundled with orn-ui. |
insets? | EdgeInsets | zeroInsets | Safe-area insets, typically from useSafeAreaInsets(). |
labels? | Partial<Labels> | defaultLabels | Override any built-in string (Close, Cancel, Search…). |
allowFontScaling? | boolean | false | Off by default, for parity across the library. |
Recommended: SafeAreaUIProvider
UIProvider defaults insets to {top:0,bottom:0,left:0,right:0} — harmless until you open a full-screen Modal (slides under the notch) or a BottomSheet (sits flush against the gesture bar). SafeAreaUIProvider is UIProvider with useSafeAreaInsets() already wired in — use it instead of UIProvider and this is handled.
It lives in its own subpath (orn-ui/safe-area), on purpose: it is the only file in the library that imports a third-party package (react-native-safe-area-context). Nothing in the main orn-ui entry point references it, so a plain import { Button } from 'orn-ui' never pulls it in — the rest of the library stays zero-dependency.
Needs react-native-safe-area-context as a peer (optional — only required if you use this import):
pnpm add react-native-safe-area-contextimport { SafeAreaUIProvider } from 'orn-ui/safe-area';
export default function App() {
return (
<SafeAreaUIProvider>
{/* your navigator / screens go here */}
</SafeAreaUIProvider>
);
}SafeAreaUIProviderProps
Plus every UIProvider prop above except insets (still accepted, but optional — it overrides the measured value instead of being required).
| Name | Type | Default | Description |
|---|---|---|---|
insets? | EdgeInsets | measured via useSafeAreaInsets() | Explicit override — wins over the measured value. Useful for tests, Storybook, or a screen that does not fill the window. |
mountSafeAreaProvider? | boolean | true | Also mount <SafeAreaProvider>. Set false if your app already has one above. |
3. Use components
Now every component page on this site works as shown — copy a variant snippet, it renders. See the component list below.
Browse components →