ReadyNative

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
  1. Set your brand in readynative.config.ts (or the full palette in src/theme/tokens.ts).
  2. bun run gen:theme - rewrites src/global.css (@theme / :root colours, dark mode via prefers-color-scheme).
  3. 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.js or babel.config.js? bun run start -- -c, or you'll chase a stale cache.
  • ThemeProvider applies the mode through VariableContextProvider; the rc prefers it over the deprecated vars().
  • 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-modules

A 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 nativewind5

Module id: ui/nativewind5.

Dependencies

PackageVersionKind
@rn-primitives/slot^1.5.2dependency
class-variance-authority^0.7.1dependency
clsx^2.1.1dependency
nativewind5.0.0-rc.0dependency
react-native-css3.1.0-rc.0dependency
tailwind-merge^3.7.0dependency
@tailwindcss/postcss^4.3.3devDependency
postcss^8.5.28devDependency
tailwindcss^4.3.3devDependency

Providers

Rendered in src/providers.tsx (lower order = outermost):

OrderProviderFrom
50ThemeProvider as UiThemeProvider@/ui

After setup

  1. Run bun run start -- -c once so Metro picks up the NativeWind transform.

Files

29 files copied to the project root
  • babel.config.js
  • metro.config.js
  • postcss.config.mjs
  • nativewind-env.d.ts
  • src/global.css
  • src/ui/nativewind5/box.tsx
  • src/ui/nativewind5/button.tsx
  • src/ui/nativewind5/card.tsx
  • src/ui/nativewind5/cn.ts
  • src/ui/nativewind5/divider.tsx
  • src/ui/nativewind5/empty-state.tsx
  • src/ui/nativewind5/error-state.tsx
  • src/ui/nativewind5/icon.tsx
  • src/ui/nativewind5/index.ts
  • src/ui/nativewind5/jest-setup.ts
  • src/ui/nativewind5/input.tsx
  • src/ui/nativewind5/list.tsx
  • src/ui/nativewind5/loading.tsx
  • src/ui/nativewind5/pressable.tsx
  • src/ui/nativewind5/rnr-button.tsx
  • src/ui/nativewind5/rnr-text.tsx
  • src/ui/nativewind5/row.tsx
  • src/ui/nativewind5/screen.tsx
  • src/ui/nativewind5/sheet.tsx
  • src/ui/nativewind5/skeleton.tsx
  • src/ui/nativewind5/switch.tsx
  • src/ui/nativewind5/text.tsx
  • src/ui/nativewind5/theme-provider.tsx
  • src/ui/nativewind5/toast.tsx

On this page

Get ReadyNative