/migrate-nativewind-to-uniwind
Migrate a React Native project from NativeWind to Uniwind. Use when the user wants to replace NativeWind with Uniwind, upgrade from NativeWind, switch to Uniwind, or mentions NativeWind-to-Uniwind migration. Handles package removal, config migration, Tailwind 4 upgrade,
$ npx -y skills add uni-stack/uniwind --skill migrate-nativewind-to-uniwind --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/migrate-nativewind-to-uniwind
Context preview
The summary Claude sees to decide when to auto-load this skill.
Migrate a React Native project from NativeWind to Uniwind. Use when the user wants to replace NativeWind with Uniwind, upgrade from NativeWind, switch to Uniwind, or mentions NativeWind-to-Uniwind migration. Handles package removal, config migration, Tailwind 4 upgrade,
SKILL.md
migrate-nativewind-to-uniwind.SKILL.mdname: migrate-nativewind-to-uniwind
description: >
Migrate a React Native project from NativeWind to Uniwind. Use when the user wants to
replace NativeWind with Uniwind, upgrade from NativeWind, switch to Uniwind, or mentions
NativeWind-to-Uniwind migration. Handles package removal, config migration, Tailwind 4
upgrade, cssInterop removal, theme conversion, and all breaking changes.
Migrate NativeWind to Uniwind
Uniwind replaces NativeWind with better performance and stability. It requires **Tailwind CSS 4** and uses CSS-based theming instead of JS config.
Pre-Migration Checklist
Before starting, read the project's existing config files to understand the current setup:
- `package.json` (NativeWind version, dependencies)
- `tailwind.config.js` / `tailwind.config.ts`
- `metro.config.js`
- `babel.config.js`
- `global.css` or equivalent CSS entry file
- `nativewind-env.d.ts` or `nativewind.d.ts`
- Any file using `cssInterop` or `remapProps` from `nativewind`
- Any file importing from `react-native-css-interop`
- Any ThemeProvider from NativeWind (`vars()` usage)
Step 1: Remove NativeWind and Related Packages
Uninstall ALL of these packages (if present):
npm uninstall nativewind react-native-css-interop
# or
yarn remove nativewind react-native-css-interop
# or
bun remove nativewind react-native-css-interop
**CRITICAL**: `react-native-css-interop` is a NativeWind dependency that must be removed. It is commonly missed during migration. Search the entire codebase for any imports from it:
rg "react-native-css-interop" -g "*.{ts,tsx,js,jsx}"Remove every import and usage found.
Step 2: Install Uniwind and Tailwind 4
npm install uniwind tailwindcss@latest
# or
yarn add uniwind tailwindcss@latest
# or
bun add uniwind tailwindcss@latest
Ensure `tailwindcss` is version 4+.
Step 3: Update babel.config.js
Remove the NativeWind babel preset:
// REMOVE this line from presets array:
// 'nativewind/babel'
No Uniwind babel preset is needed.
Step 4: Update metro.config.js
Replace NativeWind's metro config with Uniwind's. `withUniwindConfig` must be the **outermost wrapper**.
**Before (NativeWind):**
const { withNativeWind } = require('nativewind/metro');
module.exports = withNativeWind(config, { input: './global.css' });**After (Uniwind):**
const { getDefaultConfig } = require('expo/metro-config');
// For bare RN: const { getDefaultConfig } = require('@react-native/metro-config');
const { withUniwindConfig } = require('uniwind/metro');
const config = getDefaultConfig(__dirname);
module.exports = withUniwindConfig(config, {
cssEntryFile: './global.css',
polyfills: { rem: 14 },
});`cssEntryFile` must be a **relative path string** from project root (e.g. `./global.css` or `./app/global.css`). Do **not** use absolute paths or `path.resolve(...)` / `path.join(...)` for this option.
// ❌ Broken
cssEntryFile: path.resolve(__dirname, 'app', 'global.css')
// ✅ Correct
cssEntryFile: './app/global.css'
**Always set `polyfills.rem` to 14** to match NativeWind's default rem value and prevent spacing/sizing differences after migration.
If the project uses custom themes beyond `light`/`dark` (e.g. defined via NativeWind's `vars()` or a custom ThemeProvider), register them with `extraThemes`. Do NOT include `light` or `dark` — they are added automatically:
module.exports = withUniwindConfig(config, {
cssEntryFile: './global.css',
polyfills: { rem: 14 },
extraThemes: ['ocean', 'sunset', 'premium'],
});Options:
- `cssEntryFile` (required): relative path string to CSS entry file (from project root)
- `polyfills.rem` (required for migration): set to `14` to match NativeWind's rem base
- `extraThemes` (required if project has custom themes): array of custom theme names — do NOT include `light`/`dark`
- `dtsFile` (optional): path for generated TypeScript types, defaults to `./uniwind-types.d.ts`
- `debug` (optional): log unsupported CSS properties during dev
Step 5: Update global.css
Replace NativeWind's Tailwind 3 directives with Tailwind 4 imports:
**Before:**
@tailwind base;
@tailwind components;
@tailwind utilities;
**After:**
@import 'tailwindcss';
@import 'uniwind';
Step 6: Update CSS Entry Import
Ensure `global.css` is imported in your main App component (e.g., `App.tsx`), NOT in the root `index.ts`/`index.js` where you register the app — importing there breaks hot reload.
Step 7: Delete NativeWind Type Definitions
Delete `nativewind-env.d.ts` or `nativewind.d.ts`. Uniwind auto-generates its own types at the path specified by `dtsFile`.
Step 8: Delete tailwind.config.js
Remove `tailwind.config.js` / `tailwind.config.ts` entirely. All theme config moves to CSS using Tailwind 4's `@theme` directive.
Migrate custom theme values to `global.css`:
**Before (tailwind.config.js):**
module.exports = {
theme: {
extend: {
colors: {
primary: '#00a8ff',
secondary: '#273c75',
},
fontFamily: {
normal: ['Roboto-Regular'],
bold: ['Roboto-Bold'],
},
},
},
};**After (global.css):**
@import 'tailwindcss';
@import 'uniwind';
@theme {
--color-primary: #00a8ff;
--color-secondary: #273c75;
--font-normal: 'Roboto-Regular';
--font-bold: 'Roboto-Bold';
}Font families must specify a **single font** — React Native doesn't support font fallbacks.
Step 9: Remove ALL cssInterop and remapProps Usage
**This is the most commonly missed step.** Search the entire codebase:
rg "cssInterop|remapProps" -g "*.{ts,tsx,js,jsx}"Replace every `cssInterop()` / `remapProps()` call with Uniwind's `withUniwind()`:
**Before (NativeWind):**
import { cssInterop } from 'react-native-css-interop';
import { Image } from 'expo-image';
cssInterop(Image, { className: 'style' });**After (Uniwind):**
import { withUniwind } from 'uniwind';
iRead more
name: migrate-nativewind-to-uniwind description: > Migrate a React Native project from NativeWind to Uniwind. Use when the user wants to replace NativeWind with Uniwind, upgrade from NativeWind, switch to Uniwind, or mentions NativeWind-to-Uniwind migration. Handles package removal, config migration, Tailwind 4 upgrade, cssInterop removal, theme conversion, and all breaking changes.
Migrate NativeWind to Uniwind
Uniwind replaces NativeWind with better performance and stability. It requires **Tailwind CSS 4** and uses CSS-based theming instead of JS config.
Pre-Migration Checklist
Before starting, read the project's existing config files to understand the current setup:
- `package.json` (NativeWind version, dependencies)
- `tailwind.config.js` / `tailwind.config.ts`
- `metro.config.js`
- `babel.config.js`
- `global.css` or equivalent CSS entry file
- `nativewind-env.d.ts` or `nativewind.d.ts`
- Any file using `cssInterop` or `remapProps` from `nativewind`
- Any file importing from `react-native-css-interop`
- Any ThemeProvider from NativeWind (`vars()` usage)
Step 1: Remove NativeWind and Related Packages
Uninstall ALL of these packages (if present):
npm uninstall nativewind react-native-css-interop # or yarn remove nativewind react-native-css-interop # or bun remove nativewind react-native-css-interop
**CRITICAL**: `react-native-css-interop` is a NativeWind dependency that must be removed. It is commonly missed during migration. Search the entire codebase for any imports from it:
rg "react-native-css-interop" -g "*.{ts,tsx,js,jsx}"Remove every import and usage found.
Step 2: Install Uniwind and Tailwind 4
npm install uniwind tailwindcss@latest # or yarn add uniwind tailwindcss@latest # or bun add uniwind tailwindcss@latest
Ensure `tailwindcss` is version 4+.
Step 3: Update babel.config.js
Remove the NativeWind babel preset:
// REMOVE this line from presets array: // 'nativewind/babel'
No Uniwind babel preset is needed.
Step 4: Update metro.config.js
Replace NativeWind's metro config with Uniwind's. `withUniwindConfig` must be the **outermost wrapper**.
**Before (NativeWind):**
const { withNativeWind } = require('nativewind/metro');
module.exports = withNativeWind(config, { input: './global.css' });**After (Uniwind):**
const { getDefaultConfig } = require('expo/metro-config');
// For bare RN: const { getDefaultConfig } = require('@react-native/metro-config');
const { withUniwindConfig } = require('uniwind/metro');
const config = getDefaultConfig(__dirname);
module.exports = withUniwindConfig(config, {
cssEntryFile: './global.css',
polyfills: { rem: 14 },
});`cssEntryFile` must be a **relative path string** from project root (e.g. `./global.css` or `./app/global.css`). Do **not** use absolute paths or `path.resolve(...)` / `path.join(...)` for this option.
// ❌ Broken cssEntryFile: path.resolve(__dirname, 'app', 'global.css') // ✅ Correct cssEntryFile: './app/global.css'
**Always set `polyfills.rem` to 14** to match NativeWind's default rem value and prevent spacing/sizing differences after migration.
If the project uses custom themes beyond `light`/`dark` (e.g. defined via NativeWind's `vars()` or a custom ThemeProvider), register them with `extraThemes`. Do NOT include `light` or `dark` — they are added automatically:
module.exports = withUniwindConfig(config, {
cssEntryFile: './global.css',
polyfills: { rem: 14 },
extraThemes: ['ocean', 'sunset', 'premium'],
});Options:
- `cssEntryFile` (required): relative path string to CSS entry file (from project root)
- `polyfills.rem` (required for migration): set to `14` to match NativeWind's rem base
- `extraThemes` (required if project has custom themes): array of custom theme names — do NOT include `light`/`dark`
- `dtsFile` (optional): path for generated TypeScript types, defaults to `./uniwind-types.d.ts`
- `debug` (optional): log unsupported CSS properties during dev
Step 5: Update global.css
Replace NativeWind's Tailwind 3 directives with Tailwind 4 imports:
**Before:**
@tailwind base; @tailwind components; @tailwind utilities;
**After:**
@import 'tailwindcss'; @import 'uniwind';
Step 6: Update CSS Entry Import
Ensure `global.css` is imported in your main App component (e.g., `App.tsx`), NOT in the root `index.ts`/`index.js` where you register the app — importing there breaks hot reload.
Step 7: Delete NativeWind Type Definitions
Delete `nativewind-env.d.ts` or `nativewind.d.ts`. Uniwind auto-generates its own types at the path specified by `dtsFile`.
Step 8: Delete tailwind.config.js
Remove `tailwind.config.js` / `tailwind.config.ts` entirely. All theme config moves to CSS using Tailwind 4's `@theme` directive.
Migrate custom theme values to `global.css`:
**Before (tailwind.config.js):**
module.exports = {
theme: {
extend: {
colors: {
primary: '#00a8ff',
secondary: '#273c75',
},
fontFamily: {
normal: ['Roboto-Regular'],
bold: ['Roboto-Bold'],
},
},
},
};**After (global.css):**
@import 'tailwindcss';
@import 'uniwind';
@theme {
--color-primary: #00a8ff;
--color-secondary: #273c75;
--font-normal: 'Roboto-Regular';
--font-bold: 'Roboto-Bold';
}Font families must specify a **single font** — React Native doesn't support font fallbacks.
Step 9: Remove ALL cssInterop and remapProps Usage
**This is the most commonly missed step.** Search the entire codebase:
rg "cssInterop|remapProps" -g "*.{ts,tsx,js,jsx}"Replace every `cssInterop()` / `remapProps()` call with Uniwind's `withUniwind()`:
**Before (NativeWind):**
import { cssInterop } from 'react-native-css-interop';
import { Image } from 'expo-image';
cssInterop(Image, { className: 'style' });**After (Uniwind):**
import { withUniwind } from 'uniwind';
iFrom the creators of Unistyles: The fastest Tailwind bindings for React Native
Repo: uni-stack/uniwind

