React Native Theme TransitionReact Native Theme Transition

Quick Start

Define themes, wrap your app, and start using theme colors in three steps.

Setup

Define your themes

Create a single file that defines your themes and exports the API. TypeScript infers theme names and color tokens automatically.

src/lib/theme.ts
import { createThemeTransition } from 'react-native-theme-transition';

const light = {
  background: '#ffffff',
  card:       '#f5f5f5',
  text:       '#000000',
  border:     '#e0e0e0',
  primary:    '#007AFF',
  notification: '#ff3b30',
};

const dark: Record<keyof typeof light, string> = {
  background: '#000000',
  card:       '#1c1c1e',
  text:       '#ffffff',
  border:     '#333333',
  primary:    '#0A84FF',
  notification: '#ff453a',
};

export const { ThemeTransitionProvider, useTheme } =
  createThemeTransition({
    themes: { light, dark },
  });

// TypeScript infers everything:
// - Theme names: 'light' | 'dark'
// - Color tokens: 'background' | 'card' | 'text' | 'border' | 'primary' | 'notification'

Wrap your app

Place ThemeTransitionProvider as high as possible — above navigation, above modals. The screenshot captures everything inside the provider.

app/_layout.tsx
import { ThemeTransitionProvider } from '@/lib/theme';

export default function RootLayout() {
  return (
    <ThemeTransitionProvider initialTheme="system">
      <App />
    </ThemeTransitionProvider>
  );
}

Use in components

Call useTheme() to read colors, get the current theme name, and trigger transitions.

app/index.tsx
import { useTheme } from '@/lib/theme';

function MyScreen() {
  const { colors, name, setTheme, isTransitioning } = useTheme();

  return (
    <View style={{ flex: 1, backgroundColor: colors.background }}>
      <Text style={{ color: colors.text }}>Current: {name}</Text>
      <Pressable
        onPress={() => setTheme(name === 'light' ? 'dark' : 'light')}
        disabled={isTransitioning}
      >
        <Text style={{ color: colors.primary }}>Toggle theme</Text>
      </Pressable>
    </View>
  );
}

What's next?

On this page