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

global.css
tailwind.config.js
theme.ts
theme-preference.tsx
cache.ts
app/_layout.tsx
app.config.ts
scripts/generate-assets.js

Token flow

LayerFileWhat to edit
CSS variablesglobal.css--background, --primary, --ios-grouped-bg, separator, input, and grouped-surface values
Tailwind aliasestailwind.config.jsbg-background, text-foreground, bg-ios-grouped-bg, text-ios-tint, hairline borders
JS constantslib/theme.tsTHEME, IOS_COLORS, getIOSColor(), and React Navigation NAV_THEME
Componentscomponents/ui/*CVA variants and reusable primitive styling
Screensapp/**/*.tsxNativeWind 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:assets

The 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.

On this page