Skip to content

Color Scheme

Apply color scheme-specific styles using dark: and light: modifiers that automatically react to the device’s appearance settings. These work on all components in functional components and compile to conditional expressions that use React Native’s useColorScheme() hook.

import { View, Text } from "react-native";
export function ThemeCard() {
return (
<View className="bg-white dark:bg-gray-900 p-4 rounded-lg">
<Text className="text-gray-900 dark:text-white">Adapts to device theme</Text>
</View>
);
}

Transforms to:

import { useColorScheme, StyleSheet } from "react-native";
export function ThemeCard() {
const _twColorScheme = useColorScheme();
return (
<View
style={[
_twStyles._bg_white_p_4_rounded_lg,
_twColorScheme === "dark" && _twStyles._dark_bg_gray_900,
]}
>
<Text
style={[
_twStyles._text_gray_900,
_twColorScheme === "dark" && _twStyles._dark_text_white,
]}
>
Adapts to device theme
</Text>
</View>
);
}

Automatically switches between light and dark themes:

<View className="bg-white dark:bg-gray-900">
<Text className="text-gray-900 dark:text-white">Theme-aware text</Text>
</View>

Specify both light and dark mode styles explicitly:

<View className="bg-gray-100 light:bg-white dark:bg-gray-900">
<Text className="text-gray-600 light:text-gray-900 dark:text-gray-100">
Custom light & dark styles
</Text>
</View>

Combine color scheme with platform-specific styles:

<View className="p-4 ios:p-6 dark:bg-gray-900 android:rounded-xl">
<Text className="text-base dark:text-white ios:text-blue-600">
Platform + theme aware
</Text>
</View>

Card that looks great in both light and dark mode:

<View className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 p-4 rounded-lg">
<Text className="text-lg font-bold text-gray-900 dark:text-white mb-2">
Card Title
</Text>
<Text className="text-gray-600 dark:text-gray-300">
Card description text
</Text>
</View>
ModifierColor SchemeDescription
dark:Dark modeStyles when dark mode is active
light:Light modeStyles when light mode is active

The scheme: modifier is a convenience feature that automatically expands to both dark: and light: modifiers for color classes.

import { View, Text } from "react-native";
export function ThemedCard() {
return (
<View className="scheme:bg-systemGray p-4 rounded-lg">
<Text className="scheme:text-systemLabel">Adaptive system colors</Text>
</View>
);
}

Transforms to:

// Automatically expands to both dark: and light: modifiers
<View className="dark:bg-systemGray-dark light:bg-systemGray-light p-4 rounded-lg">
<Text className="dark:text-systemLabel-dark light:text-systemLabel-light">
Adaptive system colors
</Text>
</View>

Define both color variants in your tailwind.config.*:

tailwind.config.mjs
export default {
theme: {
extend: {
colors: {
// Option 1: Nested structure
systemGray: {
light: "#8e8e93",
dark: "#8e8e93",
},
systemLabel: {
light: "#000000",
dark: "#ffffff",
},
// Option 2: Flat structure with suffixes
"primary-light": "#bfdbfe",
"primary-dark": "#1e40af",
},
},
},
};

The scheme: modifier only works with color utilities:

  • scheme:text-{color} — Text colors
  • scheme:bg-{color} — Background colors
  • scheme:border-{color} — Border colors
  • ❌ Other utilities — Ignored with development warning

Semantic color names:

<View className="scheme:bg-systemBackground p-4">
<Text className="scheme:text-systemLabel">System-native appearance</Text>
<View className="scheme:border-systemSeparator border-t mt-2 pt-2">
<Text className="scheme:text-systemSecondaryLabel">Secondary text</Text>
</View>
</View>

Brand colors with theme variants:

<View className="scheme:bg-brand p-6 rounded-xl">
<Text className="scheme:text-brandContrast text-xl font-bold">
Branded Card
</Text>
<Text className="scheme:text-brandSubtle mt-2">
Automatically adapts to user's theme preference
</Text>
</View>

Mixed with other modifiers:

import { Pressable } from "@mgcrea/react-native-tailwind";
<Pressable className="scheme:bg-interactive active:opacity-80 ios:p-6 android:p-4 rounded-lg">
<Text className="scheme:text-interactiveText font-semibold">
Press Me
</Text>
</Pressable>
  • Reactive — Automatically updates when user changes system appearance
  • Zero runtime parsing — All styles compiled at build time
  • Auto-injected hookuseColorScheme() automatically added to components
  • Works with all modifiers — Combine with platform and state modifiers
  • Type-safe — Full TypeScript autocomplete
  • Optimized — Minimal runtime overhead (just conditional checks)
  • ⚠️ Functional components only — Color scheme modifiers require hooks (React Native’s useColorScheme())
    • ✅ Works with function declarations: function Component() { ... }
    • ✅ Works with arrow functions: const Component = () => { ... }
    • ✅ Works with concise arrow functions: const Component = () => <View className="dark:..." />
    • Not supported in class components — Will show a warning
  • ⚠️ React Native 0.62+ — Requires the useColorScheme API
import { View, Text, ScrollView } from "react-native";
import { Pressable } from "@mgcrea/react-native-tailwind";
export function ThemedApp() {
return (
<ScrollView className="flex-1 bg-white dark:bg-gray-900">
<View className="p-4">
<Text className="text-3xl font-bold text-gray-900 dark:text-white mb-4">
My App
</Text>
<View className="bg-gray-100 dark:bg-gray-800 rounded-lg p-4 mb-4">
<Text className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
Card Title
</Text>
<Text className="text-gray-600 dark:text-gray-300">
This card adapts to your device's theme automatically.
</Text>
</View>
<Pressable className="bg-blue-500 dark:bg-blue-600 active:bg-blue-700 dark:active:bg-blue-800 p-4 rounded-lg items-center">
<Text className="text-white font-semibold">Action Button</Text>
</Pressable>
</View>
</ScrollView>
);
}