Migrate to gluestack-ui v5
This skill migrates any gluestack-ui project to v5, regardless of the starting version. gluestack-ui v5 runs on Tailwind CSS v4 (CSS-first, no tailwind.config.js) with two supported styling engines:
*Next.js support is pending NativeWind v5 web support. Use NativeWind v4 for Next.js for now.
Step 0: Detect Your Current Version
Run in the project root:
The CLI detects your version automatically. To check manually, inspect package.json:
Automated Migration (Recommended)
The CLI handles all file changes automatically:
The wizard detects your version, walks through each upgrade step with prompts, and handles:
- Package installs / removals
global.cssrewritemetro.config.jsupdatesbabel.config.jsupdatestailwind.config.jsmigration promptspostcss.config.jscreation (NativeWind v5)lightningcsspinning (NativeWind v5)- Type definition files
Next.js projects: The automated CLI does not support Next.js upgrades yet. Follow the manual path below.
Migration Paths
v4 (NativeWind) → v5
Choose your target engine when prompted (or follow the manual steps below).
Option A: v4 NativeWind → NativeWind v5
Packages
Pin lightningcss (required — NativeWind v5 requires exactly 1.30.1):
global.css — replace contents with Tailwind v4 imports + CSS custom properties:
postcss.config.js — create at project root:
metro.config.js — ensure nativewind/metro is present:
tailwind.config.js — Tailwind v4 is CSS-first. This file is no longer needed.
- Migrate any custom
fontFamily,boxShadow,safelist,fontSize, etc. toglobal.cssusing@theme {}or@layer utilities {} - See: https://tailwindcss.com/docs/upgrade-guide
- Delete the file once migrated
react-native-css-env.d.ts — create at project root:
babel.config.js — remove the tailwind.config alias if present:
Re-add components to get NativeWind v5 versions:
Native rebuild (bare Expo or RN CLI only):
Option B: v4 NativeWind → UniWind
UniWind requires an Expo project. Next.js and RN CLI support is coming soon.
Packages
metro.config.js — switch from NativeWind to UniWind:
global.css — replace with UniWind CSS (Tailwind v4 + :where() selectors):
Web theming note: UniWind's CSS visitor transforms
:where(.dark, .dark *)to.dark {}. For this to work on Expo Web, the.dark {}/.light {}selectors must be at the top level of@layer theme— never nested inside:root {}. The template above is already correct.
tailwind.config.js — delete it. Tailwind v4 is CSS-first; all tokens live in global.css.
nativewind-env.d.ts → delete. Create uniwind-types.d.ts instead:
babel.config.js — remove nativewind/babel preset/plugin, add react-native-worklets/plugin:
GluestackUIProvider — re-add to get the UniWind version:
Key differences in the UniWind provider:
- Native: use
Uniwind.setTheme('light' | 'dark' | 'system')instead ofAppearance.setColorScheme() - Web:
script.tsadds.dark/.lightclass todocument.documentElement;Uniwind.setTheme()also callsonThemeChange()for runtime CSS variable management
v3 → v5
Step 1: Upgrade v3 → v4 (NativeWind)
tailwind.config.js — remove gluestackPlugin:
babel.config.js — add react-native-worklets/plugin:
Import updates — imports are compatible between v3 and v4 (same format). No changes needed.
Native rebuild (bare Expo / RN CLI):
Step 2: v4 NativeWind → v5
Follow Option A or Option B above.
v2 → v5
Step 1: Upgrade v2 → v3
tailwind.config.js — remove old gluestack plugin (same as v3→v4 step above).
app/registry.tsx (Next.js only) — update flush import:
next.config.js/ts/mjs (Next.js only) — update adapter import (same package, just re-save to refresh):
Import updates — update component imports across components/ui/:
Step 2: v3 → v4 → v5
Follow the v3 → v5 path above.
What Changes in v5 (Summary)
Common Issues
Mismatch between JavaScript part and native part of Worklets
react-native-worklets version must match the minor of react-native-reanimated. For Expo projects, always use npx expo install react-native-reanimated && npx expo install --fix — never pin manually.
Theme not applying on Expo Web (UniWind)
The .dark {} / .light {} selectors in global.css must be top-level inside @layer theme, not nested inside :root {}. Nesting causes UniWind's CSS visitor to emit .dark {} as a descendant of :root, so html.dark never matches.
NativeWind v5 build errors
Ensure lightningcss is pinned to exactly 1.30.1 in both overrides and resolutions in package.json, then delete node_modules and reinstall.
tailwind.config.js still referenced
After deleting tailwind.config.js, remove any 'tailwind.config': './tailwind.config.js' alias from babel.config.js presets options.
nativewind/babel still in babel.config.js (UniWind)
UniWind does not use the NativeWind Babel preset. Remove 'nativewind/babel' from both presets and plugins arrays.
After Migration Checklist
-
lightningcsspinned to1.30.1(NativeWind v5 only) -
global.cssuses Tailwind v4 imports (no@tailwind base/components/utilities) -
tailwind.config.jsdeleted and custom tokens moved toglobal.css @theme {} -
postcss.config.jscreated with@tailwindcss/postcss(NativeWind v5 only) -
metro.config.jsupdated to correct wrapper (withNativewindorwithUniwindConfig) -
babel.config.js—nativewind/babelremoved (UniWind);react-native-worklets/pluginadded -
GluestackUIProviderre-added:npx gluestack-ui@alpha add gluestack-ui-provider - All components re-added:
npx gluestack-ui@alpha add --all - Native rebuild done (bare Expo / RN CLI):
pod install+expo run:ios - App starts without errors on iOS, Android, and Web
- Light/dark mode toggles correctly on all platforms


