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.
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.
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.
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?
- API Reference — full configuration options
- Theme Picker example — segmented control with selection tracking
- System Theme — follow OS appearance automatically
- Expo Router integration — typed navigation colors