Theming
Customize NativeWind, React Native Reusables, and app theme behavior.
The Expo template uses NativeWind for app styling, React Native Reusables-style primitives for component variants, and React Navigation theme objects for native navigation surfaces. Light/dark mode is persisted as a user preference, with a system default.
Key files
Token flow
| Layer | File | What to edit |
|---|---|---|
| CSS variables | global.css | --background, --primary, --ios-grouped-bg, separator, input, and grouped-surface values |
| Tailwind aliases | tailwind.config.js | bg-background, text-foreground, bg-ios-grouped-bg, text-ios-tint, hairline borders |
| JS constants | lib/theme.ts | THEME, IOS_COLORS, getIOSColor(), and React Navigation NAV_THEME |
| Components | components/ui/* | CVA variants and reusable primitive styling |
| Screens | app/**/*.tsx | NativeWind className plus occasional getIOSColor() for runtime colors |
Keep global.css and lib/theme.ts in sync. NativeWind classes read the CSS
tokens; React Navigation and some runtime style objects read the JS tokens.
Appearance preference
ThemePreferenceProvider stores system, light, or dark under
preferences.theme.v1 using lib/cache.ts. Native platforms use AsyncStorage;
web uses localStorage. When the value hydrates, the provider calls
nativewindColorScheme.set(theme).
ThemeToggle is a compact icon button. It flips the current resolved color
scheme between light and dark. The full Profile picker exposes all three
choices, including system.
app/_layout.tsx reads useColorScheme(), applies NAV_THEME, sets the status
bar style, and gives the root stack the iOS grouped background for the active
scheme.
Splash pairing
app.config.ts deliberately matches the native splash background to the app's
grouped background: #f2f2f7 in light mode and #000000 in dark mode through
the expo-splash-screen plugin. That prevents a white or black flash before the
first React screen paints.
The optional AnimatedSplash component renders the Lottie file in
assets/lottie/splash.json over the app and fades it once isReady is true.
Rebrand checklist
Change product colors
Update global.css, tailwind.config.js aliases if needed, and lib/theme.ts.
Check both grouped backgrounds and primary/tint colors.
Replace assets
Provide a 1024x1024 source icon and run:
pnpm generate:assetsThe script writes icon.png, adaptive-icon.png, splash.png, and
favicon.png. Set SPLASH_BACKGROUND if the generated splash background should
match a custom brand color.
Update app identity
Change display names, bundle/package IDs, schemes, associated domains, and store
URLs in app.config.ts and .env.local.
Verify surfaces
Run iOS, Android, and web. Check cold launch, tab headers, modals, bottom sheets, dialogs, toast colors, the Component gallery, and the Showcase theming demo.
