Custom Color Scheme Hook
By default, the plugin uses React Native’s built-in useColorScheme() hook for dark: and light: modifiers. You can configure it to use a custom color scheme hook from theme providers like React Navigation, Expo, or your own implementation.
Configuration
Section titled “Configuration”module.exports = { plugins: [ [ "@mgcrea/react-native-tailwind/babel", { colorScheme: { importFrom: "@/hooks/useColorScheme", // Module to import from importName: "useColorScheme", // Hook name to import }, }, ], ],};Use Cases
Section titled “Use Cases”Custom Theme Provider
Section titled “Custom Theme Provider”Override system color scheme with user preferences from a store:
import { useColorScheme as useSystemColorScheme } from "react-native";import { profileStore } from "@/stores/profileStore";import { type ColorSchemeName } from "react-native";
export const useColorScheme = (): ColorSchemeName => { const systemColorScheme = useSystemColorScheme(); const userTheme = profileStore.theme; // 'dark' | 'light' | 'auto'
// Return user preference, or fall back to system if set to 'auto' return userTheme === 'auto' ? systemColorScheme : userTheme;};{ colorScheme: { importFrom: "@/hooks/useColorScheme", importName: "useColorScheme" }}React Navigation Theme
Section titled “React Navigation Theme”Integrate with React Navigation’s theme system:
import { useTheme as useNavTheme } from "@react-navigation/native";import { type ColorSchemeName } from "react-native";
export const useColorScheme = (): ColorSchemeName => { const { dark } = useNavTheme(); return dark ? "dark" : "light";};{ colorScheme: { importFrom: "@/hooks/useColorScheme", importName: "useColorScheme" }}Expo Router Theme
Section titled “Expo Router Theme”Use Expo Router’s theme hook:
{ colorScheme: { importFrom: "expo-router", importName: "useColorScheme" }}Testing
Section titled “Testing”Mock color scheme for tests:
export const useColorScheme = () => "light"; // Or "dark" for dark mode tests// babel.config.js (test environment){ colorScheme: { importFrom: "@/test/mocks/useColorScheme", importName: "useColorScheme" }}How It Works
Section titled “How It Works”When you use dark: or light: modifiers:
<View className="bg-white dark:bg-gray-900" />The plugin will:
- Import your custom hook:
import { useColorScheme } from "@/hooks/useColorScheme" - Inject it in components:
const _twColorScheme = useColorScheme(); - Generate conditionals:
_twColorScheme === "dark" && styles._dark_bg_gray_900
Default Behavior
Section titled “Default Behavior”Without custom configuration, the plugin uses React Native’s built-in hook:
import { useColorScheme } from "react-native"This works out of the box for basic system color scheme detection.
Requirements
Section titled “Requirements”- Your custom hook must return
ColorSchemeName(type from React Native:"light" | "dark" | null | undefined) - The hook must be compatible with React’s rules of hooks (can only be called in function components)
- Import merging works automatically if you already import from the same source
Complete Example
Section titled “Complete Example”import { createContext, useContext, useState, ReactNode } from "react";import { useColorScheme as useSystemColorScheme } from "react-native";import { type ColorSchemeName } from "react-native";
type ThemeContextType = { colorScheme: ColorSchemeName; setColorScheme: (scheme: "light" | "dark" | "auto") => void;};
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export function ThemeProvider({ children }: { children: ReactNode }) { const systemColorScheme = useSystemColorScheme(); const [userPreference, setUserPreference] = useState<"light" | "dark" | "auto">("auto");
const colorScheme = userPreference === "auto" ? systemColorScheme : userPreference;
return ( <ThemeContext.Provider value={{ colorScheme, setColorScheme: setUserPreference }}> {children} </ThemeContext.Provider> );}
export function useColorScheme(): ColorSchemeName { const context = useContext(ThemeContext); if (!context) throw new Error("useColorScheme must be used within ThemeProvider"); return context.colorScheme;}module.exports = { plugins: [ [ "@mgcrea/react-native-tailwind/babel", { colorScheme: { importFrom: "@/context/ThemeContext", importName: "useColorScheme", }, }, ], ],};Now your components will use the custom hook:
function MyComponent() { // Uses your custom useColorScheme from ThemeContext return ( <View className="bg-white dark:bg-gray-900"> <Text className="text-gray-900 dark:text-white">Theme-aware text</Text> </View> );}Related
Section titled “Related”- Color Scheme - Using color scheme modifiers
- Babel Configuration - All plugin options
- Custom Colors - Extend color palette