Skip to main content
The useColorScheme hook detects the current color scheme preference of the user’s device. It returns either 'light', 'dark', or null if the color scheme cannot be determined.

Platform Differences

This hook has different implementations for native and web platforms:
  • Native (iOS/Android): Directly exports React Native’s useColorScheme hook
  • Web: Implements hydration-aware logic to support static rendering

Web Implementation

On web, the hook includes special handling for server-side rendering and static site generation:
import { useEffect, useState } from 'react';
import { useColorScheme as useRNColorScheme } from 'react-native';

export function useColorScheme() {
  const [hasHydrated, setHasHydrated] = useState(false);

  useEffect(() => {
    setHasHydrated(true);
  }, []);

  const colorScheme = useRNColorScheme();

  if (hasHydrated) {
    return colorScheme;
  }

  return 'light';
}
This prevents hydration mismatches by defaulting to 'light' during SSR and updating after client-side hydration.

Usage

Basic Usage

import { useColorScheme } from '@/hooks/use-color-scheme';

export default function RootLayout() {
  const colorScheme = useColorScheme();

  return (
    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      {/* Your app content */}
    </ThemeProvider>
  );
}

With Tab Bar Icons

import { Tabs } from 'expo-router';
import { useColorScheme } from '@/hooks/use-color-scheme';
import { Colors } from '@/constants/theme';

export default function TabLayout() {
  const colorScheme = useColorScheme();

  return (
    <Tabs
      screenOptions={{
        tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
      }}>
      {/* Tab screens */}
    </Tabs>
  );
}

With Conditional Rendering

import { useColorScheme } from '@/hooks/use-color-scheme';

export function ParallaxScrollView() {
  const colorScheme = useColorScheme() ?? 'light';
  
  return (
    <ParallaxScrollView
      headerImage={
        <Ionicons
          size={310}
          name="code-slash"
          style={styles.headerImage}
          color={colorScheme === 'dark' ? '#1D3D47' : '#D0D0D0'}
        />
      }>
      {/* Content */}
    </ParallaxScrollView>
  );
}

Return Value

colorScheme
'light' | 'dark' | null
The current color scheme preference:
  • 'light' - Light mode is active
  • 'dark' - Dark mode is active
  • null - Color scheme cannot be determined (rare)
On web, returns 'light' during SSR before hydration completes.

Source Files

  • Native: /hooks/use-color-scheme.ts
  • Web: /hooks/use-color-scheme.web.ts

Build docs developers (and LLMs) love