Last updated on March 30, 2026

Dynamic Themes

Edit

Nativewind v5 supports dynamic theming through CSS variables and the VariableContextProvider component. This lets you change colors, spacing, and other design tokens at runtime without rebuilding your stylesheet.

For static theme customization (adding custom colors, fonts, spacing), see the Theme documentation. For dark mode specifically, see Dark Mode.

How It Works

  1. Define CSS variables in your global.css using @theme and :root
  2. Reference those variables in your utility classes (e.g. bg-primary, text-secondary)
  3. Override the variables at runtime using VariableContextProvider

The provider uses React context, so any component wrapped by it (and its children) will pick up the overridden values.

Basic Example

First, define your theme variables in CSS:

global.css
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css";
@import "nativewind/theme";
 
@theme {
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
}
 
:root {
  --color-primary: #3b82f6;
  --color-secondary: #8b5cf6;
}

You need to define the variables in both @theme (so Tailwind generates the utility classes) and :root (so the CSS variables have default values at runtime).

Then override them at runtime:

App.tsx
import { View, Text } from "react-native";
import { VariableContextProvider } from "nativewind";
 
const christmasTheme = {
  "--color-primary": "red",
  "--color-secondary": "green",
};
 
export default function App() {
  return (
    <View>
      <Text className="text-primary">Blue (default)</Text>
 
      <VariableContextProvider value={christmasTheme}>
        <Text className="text-primary">Red (christmas)</Text>
        <Text className="text-secondary">Green (christmas)</Text>
      </VariableContextProvider>
    </View>
  );
}

Multiple Themes with Light/Dark Mode

Combine VariableContextProvider with useColorScheme from react-native to support multiple themes that each have light and dark variants:

components/ThemeProvider.tsx
import { useColorScheme } from "react-native";
import { VariableContextProvider } from "nativewind";
 
const themes = {
  brand: {
    light: {
      "--color-foreground": "#000000",
      "--color-muted-foreground": "#64748b",
      "--color-primary": "#3b82f6",
      "--color-secondary": "#8b5cf6",
    },
    dark: {
      "--color-foreground": "#ffffff",
      "--color-muted-foreground": "#a1a1a1",
      "--color-primary": "#60a5fa",
      "--color-secondary": "#a78bfa",
    },
  },
  christmas: {
    light: {
      "--color-foreground": "#000000",
      "--color-muted-foreground": "#64748b",
      "--color-primary": "#dc2626",
      "--color-secondary": "#16a34a",
    },
    dark: {
      "--color-foreground": "#ffffff",
      "--color-muted-foreground": "#a1a1a1",
      "--color-primary": "#f87171",
      "--color-secondary": "#4ade80",
    },
  },
};
 
export function ThemeProvider({
  name,
  children,
}: {
  name: keyof typeof themes;
  children: React.ReactNode;
}) {
  const colorScheme = useColorScheme() ?? "light";
 
  return (
    <VariableContextProvider value={themes[name][colorScheme]}>
      {children}
    </VariableContextProvider>
  );
}
app/_layout.tsx
import "../global.css";
import { ThemeProvider } from "@/components/ThemeProvider";
 
export default function RootLayout() {
  return (
    <ThemeProvider name="brand">
      <Stack />
    </ThemeProvider>
  );
}

Nesting Themes

VariableContextProvider inherits from its parent context. You can nest providers to override specific variables while keeping the rest:

<VariableContextProvider value={{ "--color-primary": "blue" }}>
  <Text className="text-primary">Blue</Text>
 
  <VariableContextProvider value={{ "--color-primary": "red" }}>
    <Text className="text-primary">Red (overridden)</Text>
  </VariableContextProvider>
</VariableContextProvider>

Migrating from v4

If you used vars() in v4, replace it with VariableContextProvider:

- import { vars } from "nativewind";
+ import { VariableContextProvider } from "nativewind";
 
- const theme = vars({ "--color-primary": "red" });
 
- <View style={theme}>
-   {children}
- </View>
 
+ <VariableContextProvider value={{ "--color-primary": "red" }}>
+   {children}
+ </VariableContextProvider>

vars() is deprecated and will be removed in a future release.

Platform-Specific Theme Values

Use CSS media queries to set platform-specific defaults:

global.css
@theme {
  --color-error: var(--error-color, green);
}
 
@media ios {
  :root {
    --error-color: red;
  }
}
 
@media android {
  :root {
    --error-color: blue;
  }
}

These can still be overridden at runtime via VariableContextProvider.

On this page