npx gluestack-ui@alpha upgrade◆ Which styling engine would you like to upgrade to?
│ ● NativeWind v5 (Tailwind CSS v4)
│ ○ UniWind (Tailwind CSS v4, Expo-only)
│ ○ Stay on current version| Area | Before (NativeWind v4) | After (NativeWind v5) |
|---|---|---|
| Tailwind version | tailwindcss@^3.x | tailwindcss@^4.2.0 |
| NativeWind version | nativewind@^4.1.23 | nativewind@^5.0.0-preview.2 |
| New package | — | react-native-css@^3.0.4 |
| PostCSS config | — | postcss.config.js with @tailwindcss/postcss |
| Theme tokens | tailwind.config.js | global.css via @layer theme |
| metro.config.js | withNativewind (same) | withNativewind from nativewind/metro |
| Type declarations | nativewind-env.d.ts | react-native-css-env.d.ts |
| lightningcss | — | Must pin to 1.30.1 |
npx gluestack-ui@alpha upgradenpx gluestack-ui add button accordion modal # all components you use
{
"overrides": { "lightningcss": "1.30.1" },
"resolutions": { "lightningcss": "1.30.1" }
}
npm install nativewind@^5.0.0-preview.2 react-native-css@^3.0.4 @gluestack-ui/core@^5.0.0-alpha.0 @gluestack-ui/utils@^5.0.1-alpha.0
npm install --save-dev tailwindcss@^4.2.0 @tailwindcss/postcss@^4.2.0export default {
plugins: {
"@tailwindcss/postcss": {},
},
};
const { getDefaultConfig } = require("expo/metro-config");
const { withNativewind } = require("nativewind/metro");
const config = getDefaultConfig(__dirname);
module.exports = withNativewind(config);
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css";
@import "nativewind/theme";
@layer theme {
:root {
--primary: 23 23 23;
--primary-foreground: 250 250 250;
--card: 255 255 255;
--secondary: 245 245 245;
--secondary-foreground: 23 23 23;
--background: 255 255 255;
--popover: 255 255 255;
--popover-foreground: 10 10 10;
--muted: 245 245 245;
--muted-foreground: 115 115 115;
--destructive: 231 0 11;
--foreground: 10 10 10;
--border: 229 229 229;
--input: 229 229 229;
--ring: 212 212 212;
--accent: 247 247 247;
--accent-foreground: 52 52 52;
}
@media (prefers-color-scheme: dark) {
:root {
--primary: 255 245 245;
--primary-foreground: 23 23 23;
--card: 23 23 23;
--secondary: 38 38 38;
--secondary-foreground: 250 250 250;
--background: 10 10 10;
--popover: 23 23 23;
--popover-foreground: 250 250 250;
--muted: 38 38 38;
--muted-foreground: 161 161 161;
--destructive: 255 100 103;
--foreground: 250 250 250;
--border: 46 46 46;
--input: 46 46 46;
--ring: 115 115 115;
--accent: 38 38 38;
--accent-foreground: 250 250 250;
}
}
/* Web: class-based toggle overrides media query */
:root.dark {
--primary: 255 245 245;
--primary-foreground: 23 23 23;
--card: 23 23 23;
--secondary: 38 38 38;
--secondary-foreground: 250 250 250;
--background: 10 10 10;
--popover: 23 23 23;
--popover-foreground: 250 250 250;
--muted: 38 38 38;
--muted-foreground: 161 161 161;
--destructive: 255 100 103;
--foreground: 250 250 250;
--border: 46 46 46;
--input: 46 46 46;
--ring: 115 115 115;
--accent: 38 38 38;
--accent-foreground: 250 250 250;
}
:root.light {
--primary: 23 23 23;
--primary-foreground: 250 250 250;
--card: 255 255 255;
--secondary: 245 245 245;
--secondary-foreground: 23 23 23;
--background: 255 255 255;
--popover: 255 255 255;
--popover-foreground: 10 10 10;
--muted: 245 245 245;
--muted-foreground: 115 115 115;
--destructive: 231 0 11;
--foreground: 10 10 10;
--border: 229 229 229;
--input: 229 229 229;
--ring: 212 212 212;
--accent: 247 247 247;
--accent-foreground: 52 52 52;
}
}
@theme inline {
--color-primary: rgb(var(--primary));
--color-primary-foreground: rgb(var(--primary-foreground));
--color-card: rgb(var(--card));
--color-secondary: rgb(var(--secondary));
--color-secondary-foreground: rgb(var(--secondary-foreground));
--color-background: rgb(var(--background));
--color-popover: rgb(var(--popover));
--color-popover-foreground: rgb(var(--popover-foreground));
--color-muted: rgb(var(--muted));
--color-muted-foreground: rgb(var(--muted-foreground));
--color-destructive: rgb(var(--destructive));
--color-foreground: rgb(var(--foreground));
--color-border: rgb(var(--border));
--color-input: rgb(var(--input));
--color-ring: rgb(var(--ring));
--color-accent: rgb(var(--accent));
--color-accent-foreground: rgb(var(--accent-foreground));
}
/// <reference types="react-native-css/types" />
npx gluestack-ui add button accordion modal # all components you use
| Area | Before (NativeWind v4) | After (UniWind) |
|---|---|---|
| Styling engine | nativewind@^4.1.23 | uniwind@^1.3.0 |
| Tailwind version | tailwindcss@^3.x | tailwindcss@^4.1.18 |
| metro.config.js | withNativewind | withUniwindConfig from uniwind/metro |
| Theme tokens | tailwind.config.js | global.css with .light / .dark |
| babel.config.js | nativewind/babel plugin | Remove nativewind/babel |
| Type declarations | nativewind-env.d.ts | uniwind-types.d.ts |
npx gluestack-ui@alpha upgradenpx gluestack-ui add button accordion modal # all components you use
npm install uniwind@^1.3.0 @gluestack-ui/core@^5.0.0-alpha.0 @gluestack-ui/utils@^5.0.1-alpha.0
npm install --save-dev tailwindcss@^4.1.18
npm uninstall nativewindconst { getDefaultConfig } = require("expo/metro-config");
const { withUniwindConfig } = require("uniwind/metro");
const config = getDefaultConfig(__dirname);
module.exports = withUniwindConfig(config, {
cssEntryFile: "./global.css",
themes: ["light", "dark"],
});
@import "tailwindcss";
@layer theme {
.light {
--primary: 23 23 23;
--primary-foreground: 250 250 250;
--card: 255 255 255;
--secondary: 245 245 245;
--secondary-foreground: 23 23 23;
--background: 255 255 255;
--popover: 255 255 255;
--popover-foreground: 10 10 10;
--muted: 245 245 245;
--muted-foreground: 115 115 115;
--destructive: 231 0 11;
--foreground: 10 10 10;
--border: 229 229 229;
--input: 229 229 229;
--ring: 212 212 212;
--accent: 247 247 247;
--accent-foreground: 52 52 52;
}
@media (prefers-color-scheme: light) {
:root:not(:where(.light, .light *, .dark, .dark *)) {
--primary: 23 23 23;
--primary-foreground: 250 250 250;
--card: 255 255 255;
--secondary: 245 245 245;
--secondary-foreground: 23 23 23;
--background: 255 255 255;
--popover: 255 255 255;
--popover-foreground: 10 10 10;
--muted: 245 245 245;
--muted-foreground: 115 115 115;
--destructive: 231 0 11;
--foreground: 10 10 10;
--border: 229 229 229;
--input: 229 229 229;
--ring: 212 212 212;
--accent: 247 247 247;
--accent-foreground: 52 52 52;
}
}
.dark {
--primary: 255 245 245;
--primary-foreground: 23 23 23;
--card: 23 23 23;
--secondary: 38 38 38;
--secondary-foreground: 250 250 250;
--background: 10 10 10;
--popover: 23 23 23;
--popover-foreground: 250 250 250;
--muted: 38 38 38;
--muted-foreground: 161 161 161;
--destructive: 255 100 103;
--foreground: 250 250 250;
--border: 46 46 46;
--input: 46 46 46;
--ring: 115 115 115;
--accent: 38 38 38;
--accent-foreground: 250 250 250;
}
@media (prefers-color-scheme: dark) {
:root:not(:where(.light, .light *, .dark, .dark *)) {
--primary: 255 245 245;
--primary-foreground: 23 23 23;
--card: 23 23 23;
--secondary: 38 38 38;
--secondary-foreground: 250 250 250;
--background: 10 10 10;
--popover: 23 23 23;
--popover-foreground: 250 250 250;
--muted: 38 38 38;
--muted-foreground: 161 161 161;
--destructive: 255 100 103;
--foreground: 250 250 250;
--border: 46 46 46;
--input: 46 46 46;
--ring: 115 115 115;
--accent: 38 38 38;
--accent-foreground: 250 250 250;
}
}
}
@theme inline {
--color-primary: rgb(var(--primary));
--color-primary-foreground: rgb(var(--primary-foreground));
--color-card: rgb(var(--card));
--color-secondary: rgb(var(--secondary));
--color-secondary-foreground: rgb(var(--secondary-foreground));
--color-background: rgb(var(--background));
--color-popover: rgb(var(--popover));
--color-popover-foreground: rgb(var(--popover-foreground));
--color-muted: rgb(var(--muted));
--color-muted-foreground: rgb(var(--muted-foreground));
--color-destructive: rgb(var(--destructive));
--color-foreground: rgb(var(--foreground));
--color-border: rgb(var(--border));
--color-input: rgb(var(--input));
--color-ring: rgb(var(--ring));
--color-accent: rgb(var(--accent));
--color-accent-foreground: rgb(var(--accent-foreground));
}
// Before
module.exports = {
presets: ['babel-preset-expo'],
plugins: ['nativewind/babel'], // ← remove this
};
// After
module.exports = {
presets: ['babel-preset-expo'],
plugins: [],
};
/// <reference types="uniwind/types" />
npx gluestack-ui add button accordion modal # all components you use