Skip to content
Development
Skill

/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,

From plugin
uniwind
1.7k2 skills
Install
$ npx -y skills add uni-stack/uniwind --skill migrate-nativewind-to-uniwind --agent claude-code

How 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.md
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';
i
Read more
Ships withuniwind

From the creators of Unistyles: The fastest Tailwind bindings for React Native

Get the whole plugin
Stats
1,667
Stars
46
Forks
Active
Maintenance
TypeScript
Language
MIT
License
8h ago
Last commit
1y ago
Created

Repo: uni-stack/uniwind