The React Native Boilerplate includes a comprehensive theming system that supports dynamic theme switching, responsive design, and consistent styling across your app.
Switch between light and dark themes at runtime
Adaptive layouts for different screen sizes
TypeScript support for theme properties
Easy to extend and modify
Understanding the theme system architecture
src/theme/
├── index.ts # Main theme exports
├── colors.ts # Color definitions
├── typography.ts # Font and text styles
├── spacing.ts # Margins, padding, gaps
├── shadows.ts # Shadow definitions
└── components/ # Component-specific styles
├── button.ts
├── card.ts
└── input.tsDefining and using colors in your theme
// src/theme/colors.ts
export const colors = {
light: {
primary: '#007AFF',
secondary: '#5856D6',
background: '#FFFFFF',
surface: '#F2F2F7',
text: '#000000',
textSecondary: '#8E8E93',
border: '#C6C6C8',
error: '#FF3B30',
warning: '#FF9500',
success: '#34C759',
},
dark: {
primary: '#0A84FF',
secondary: '#5E5CE6',
background: '#000000',
surface: '#1C1C1E',
text: '#FFFFFF',
textSecondary: '#8E8E93',
border: '#38383A',
error: '#FF453A',
warning: '#FF9F0A',
success: '#30D158',
},
};// In your components
import { useTheme } from '@/hooks/useTheme';
const MyComponent = () => {
const { colors } = useTheme();
return (
<View style={{ backgroundColor: colors.background }}>
<Text style={{ color: colors.text }}>
Hello World
</Text>
</View>
);
};Consistent text styling across your app
// src/theme/typography.ts
export const typography = {
heading1: {
fontSize: 32,
fontWeight: '700',
lineHeight: 40,
},
heading2: {
fontSize: 24,
fontWeight: '600',
lineHeight: 32,
},
body: {
fontSize: 16,
fontWeight: '400',
lineHeight: 24,
},
caption: {
fontSize: 12,
fontWeight: '400',
lineHeight: 16,
},
};import { useTheme } from '@/hooks/useTheme';
const TextExample = () => {
const { typography, colors } = useTheme();
return (
<>
<Text style={[typography.heading1, { color: colors.text }]}>
Main Title
</Text>
<Text style={[typography.body, { color: colors.textSecondary }]}>
Body text content
</Text>
</>
);
};Implementing theme switching functionality
// src/contexts/ThemeContext.tsx
import React, { createContext, useContext, useState } from 'react';
type Theme = 'light' | 'dark';
interface ThemeContextType {
theme: Theme;
toggleTheme: () => void;
colors: typeof colors.light;
typography: typeof typography;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [theme, setTheme] = useState<Theme>('light');
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
const value = {
theme,
toggleTheme,
colors: colors[theme],
typography,
};
return (
<ThemeContext.Provider value={value}>
{children}
</ThemeContext.Provider>
);
};// src/components/ThemeToggle.tsx
import React from 'react';
import { TouchableOpacity } from 'react-native';
import { useTheme } from '@/hooks/useTheme';
import Icon from 'react-native-vector-icons/Ionicons';
export const ThemeToggle = () => {
const { theme, toggleTheme, colors } = useTheme();
return (
<TouchableOpacity
onPress={toggleTheme}
style={{
padding: 12,
backgroundColor: colors.surface,
borderRadius: 8,
}}
>
<Icon
name={theme === 'light' ? 'moon' : 'sunny'}
size={24}
color={colors.text}
/>
</TouchableOpacity>
);
};Creating reusable styled components
// src/components/Button.tsx
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
import { useTheme } from '@/hooks/useTheme';
interface ButtonProps {
title: string;
onPress: () => void;
variant?: 'primary' | 'secondary';
}
export const Button: React.FC<ButtonProps> = ({
title,
onPress,
variant = 'primary'
}) => {
const { colors, typography } = useTheme();
const buttonStyle = {
backgroundColor: variant === 'primary' ? colors.primary : colors.secondary,
padding: 16,
borderRadius: 8,
alignItems: 'center' as const,
};
const textStyle = {
...typography.body,
color: '#FFFFFF',
fontWeight: '600' as const,
};
return (
<TouchableOpacity style={buttonStyle} onPress={onPress}>
<Text style={textStyle}>{title}</Text>
</TouchableOpacity>
);
};Guidelines for effective theming