NativeWind 5
Set up NativeWind 5 for UI in an Expo app with ReadyNative: RC · Tailwind 4 classes behind @/ui · Expo Go OK
Expo Go: yes
Runs in Expo Go; no dev build needed for this module.
RC · Tailwind 4. Tailwind 4 classes compiled by react-native-css, as the kit in src/components/ui/ (src/ui/nativewind5/ before setup). NativeWind 5 is still a release candidate, so it is not the default (that is nativewind4, the stable release); pick it if you want Tailwind 4 today and accept an RC. Pure JS, so Expo Go works.
nativewind@5.0.0-rc.0 and react-native-css@3.1.0-rc.0 are pinned as a pair - NativeWind's peer dependency names the engine version exactly. The module also adds a lightningcss override to package.json (both pin 1.30.1; without it npm hoists a newer one and Metro fails to parse src/global.css).
Setup
bun run setup --ui nativewind5- Set your brand in
readynative.config.ts(or the full palette insrc/theme/tokens.ts). bun run gen:theme- rewritessrc/global.css(@theme/:rootcolours, dark mode viaprefers-color-scheme).bun run start -- -c- once, so Metro picks up the NativeWind transform.
Setup writes babel.config.js, metro.config.js, postcss.config.mjs and nativewind-env.d.ts, registers ThemeProvider (order 50) and pins lightningcss@1.30.1 as a package override for Tailwind 4's native binary.
Usage
Screens use the primitives:
import { Box, Button, Screen, Text } from "@/components/ui";
<Screen scroll>
<Box p={4} gap={2}>
<Text variant="title">Profile</Text>
<Button onPress={save}>Save</Button>
</Box>
</Screen>;Your own components use classes; the token names are the colours:
export function Badge({ children }: BadgeProps) {
return <View className="rounded-full bg-primary px-3 py-1">{children}</View>;
}Anything dynamic reads useTheme() - p-${n} can't be generated at runtime.
To add a primitive to the kit: create it in src/components/ui/, add its prop type to src/components/ui/types.ts, and export it from src/components/ui/index.ts.
Gotchas
- Changed
metro.config.jsorbabel.config.js?bun run start -- -c, or you'll chase a stale cache. ThemeProviderapplies the mode throughVariableContextProvider; the rc prefers it over the deprecatedvars().- Before setup, or with
--keep-modules,bun run setup --ui <other>swaps the adapter, config and deps. Screens don't change.
Remove it
Every app needs a ui option, so there is no none to fall back to - you switch instead. While modules/ exists (a tree set up with --keep-modules), one call does it:
bun run setup --ui nativewind4 --yes --keep-modulesA finalized tree can't switch: clone a fresh copy of your tier repo, run setup there with the new option and port your code across - see Can I change a module after setup?.
Reference
Everything below is generated from modules/ui/nativewind5/module.json - the same file bun run setup reads, so it is what actually lands in your repo.
Install
bun run setup --ui nativewind5Module id: ui/nativewind5.
Dependencies
| Package | Version | Kind |
|---|---|---|
@rn-primitives/slot | ^1.5.2 | dependency |
class-variance-authority | ^0.7.1 | dependency |
clsx | ^2.1.1 | dependency |
nativewind | 5.0.0-rc.0 | dependency |
react-native-css | 3.1.0-rc.0 | dependency |
tailwind-merge | ^3.7.0 | dependency |
@tailwindcss/postcss | ^4.3.3 | devDependency |
postcss | ^8.5.28 | devDependency |
tailwindcss | ^4.3.3 | devDependency |
Providers
Rendered in src/providers.tsx (lower order = outermost):
| Order | Provider | From |
|---|---|---|
| 50 | ThemeProvider as UiThemeProvider | @/ui |
After setup
- Run
bun run start -- -conce so Metro picks up the NativeWind transform.
Files
29 files copied to the project root
babel.config.jsmetro.config.jspostcss.config.mjsnativewind-env.d.tssrc/global.csssrc/ui/nativewind5/box.tsxsrc/ui/nativewind5/button.tsxsrc/ui/nativewind5/card.tsxsrc/ui/nativewind5/cn.tssrc/ui/nativewind5/divider.tsxsrc/ui/nativewind5/empty-state.tsxsrc/ui/nativewind5/error-state.tsxsrc/ui/nativewind5/icon.tsxsrc/ui/nativewind5/index.tssrc/ui/nativewind5/jest-setup.tssrc/ui/nativewind5/input.tsxsrc/ui/nativewind5/list.tsxsrc/ui/nativewind5/loading.tsxsrc/ui/nativewind5/pressable.tsxsrc/ui/nativewind5/rnr-button.tsxsrc/ui/nativewind5/rnr-text.tsxsrc/ui/nativewind5/row.tsxsrc/ui/nativewind5/screen.tsxsrc/ui/nativewind5/sheet.tsxsrc/ui/nativewind5/skeleton.tsxsrc/ui/nativewind5/switch.tsxsrc/ui/nativewind5/text.tsxsrc/ui/nativewind5/theme-provider.tsxsrc/ui/nativewind5/toast.tsx