Quick Setup
Get RNC Theme working in your Expo Router app in just a few minutes with this comprehensive guide.
Quick Setup
Get RNC Theme working in your Expo Router app in just a few minutes with this comprehensive guide.
Choose your preferred package manager to initialize your Expo project:
npx create-expo-app@latest my-rnc-appcd my-rnc-app
yarn create expo-app my-rnc-appcd my-rnc-app
pnpm create expo-app my-rnc-appcd my-rnc-app
bun create expo my-rnc-appcd my-rnc-app
Setup the Provider
Configure RNC Theme in your root layout file to enable theming across your entire app.
import { useFonts } from 'expo-font';import { Stack } from 'expo-router';import { StatusBar } from 'expo-status-bar';import { RNCProvider } from 'rnc-theme';import { GestureHandlerRootView } from 'react-native-gesture-handler';import 'react-native-reanimated';
export default function RootLayout() { const [loaded] = useFonts({ SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), });
if (!loaded) { return null; }
return ( <GestureHandlerRootView> <RNCProvider defaultTheme="system"> <Stack> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name="+not-found" /> </Stack> <StatusBar style="auto" /> </RNCProvider> </GestureHandlerRootView> );}
Create Your First Screen
Build a home screen that demonstrates basic theming capabilities:
import { Link } from "expo-router";import { Moon, Sun } from "lucide-react-native";import React from "react";import { ScrollView, StyleSheet, Text, TouchableOpacity } from "react-native";import { Theme, useTheme, useThemedStyles } from "rnc-theme";
export default function HomeScreen() { const { theme, setThemeMode, isDark } = useTheme(); const styles = useThemedStyles(createStyles);
const toggleTheme = () => { setThemeMode(isDark ? "light" : "dark"); };
return ( <ScrollView style={styles.container} contentContainerStyle={{ flexGrow: 1, justifyContent: "center", alignItems: "center" }} > <Text style={styles.title}>Welcome to RNC Theme!</Text> <Text style={styles.subtitle}> Current theme: {isDark ? "dark" : "light"} </Text>
<TouchableOpacity style={styles.button} onPress={toggleTheme}> {isDark ? ( <Sun color={theme.colors.text} size={20} /> ) : ( <Moon color={theme.colors.text} size={20} /> )} <Text style={styles.buttonText}>Toggle Theme</Text> </TouchableOpacity>
<Link href="/explore" style={styles.link}> <Text style={styles.linkText}>Go to Explore</Text> </Link> </ScrollView> );}
const createStyles = (theme: Theme) => StyleSheet.create({ container: { flex: 1, backgroundColor: theme.colors.background, padding: theme.spacing.lg, }, title: { fontSize: 28, fontWeight: "bold", color: theme.colors.text, textAlign: "center", marginBottom: theme.spacing.sm, }, subtitle: { fontSize: 16, color: theme.colors.textSecondary, textAlign: "center", marginBottom: theme.spacing.xl, }, button: { backgroundColor: theme.colors.primary, flexDirection: "row", alignItems: "center", justifyContent: "center", paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.md, borderRadius: theme.components.borderRadius.md, gap: theme.spacing.sm, marginBottom: theme.spacing.lg, }, buttonText: { color: theme.colors.text, fontSize: 16, fontWeight: "600", }, link: { alignSelf: "center", }, linkText: { color: theme.colors.primary, fontSize: 16, fontWeight: "500", },});
Try Built-in Components
Create a profile screen showcasing RNC Theme’s pre-built components:
import { Settings, User } from "lucide-react-native";import React, { useState } from "react";import { Avatar, Box, Button, ButtonIcon, ButtonText, Card, Center, Heading, HStack, Input, Subtitle, Switcher, Title, useTheme, useToast, VStack} from "rnc-theme";
export default function ProfileScreen() { const [name, setName] = useState(""); const [notifications, setNotifications] = useState(false); const { theme } = useTheme(); const { toast } = useToast();
const showToast = () => { toast({ title: "Settings Saved", description: "Your preferences have been updated successfully.", variant: "success" }); };
return ( <Box flex={1} backgroundColor="background" padding="lg" style={{ paddingTop: 80 }} > <VStack spacing="lg"> <Card padding="lg"> <VStack spacing="md" align="center"> <Avatar source={{ uri: "https://github.com/masumrpg.png" }} size="xl" borderWidth={2} borderColor={theme.colors.primary} /> <Center> <Heading>Masum</Heading> <Title>Software Developer</Title> </Center> </VStack> </Card>
<Card padding="lg"> <VStack spacing="md"> <Box> <Title>Settings</Title> </Box>
<Input placeholder="Enter your name..." value={name} onChangeText={setName} leftIcon={<User color={theme.colors.text} size={20} />} />
<HStack align="center" justify="space-between"> <Box> <Subtitle>Enable notifications</Subtitle> </Box> <Switcher value={notifications} onValueChange={setNotifications} /> </HStack>
<HStack spacing="sm"> <Button variant="default" onPress={showToast}> <ButtonText>Save Changes</ButtonText> </Button> <Button variant="outline"> <ButtonIcon icon={<Settings color={theme.colors.primary} size={20} />} /> <ButtonText>More Settings</ButtonText> </Button> </HStack> </VStack> </Card> </VStack> </Box> );}
Automatic Theming
Light/dark mode with system preference support and smooth transitions.
30+ Components
Pre-built, accessible components that follow design system principles.
TypeScript Support
Full type safety with IntelliSense and auto-completion.
Consistent Styling
Unified spacing, colors, and typography across your entire app.
Performance Optimized
Efficient re-renders and optimized component lifecycle management.
npm run ios# ornpx expo run:ios
npm run android# ornpx expo run:android
npm start# Scan QR code with Expo Go app
Theme Not Persisting
Problem: Theme changes don’t persist between app restarts Solution: Check AsyncStorage permissions and ensure the provider is at the root level
// Ensure RNCProvider wraps your entire app<RNCProvider> <App /></RNCProvider>
Styles Not Updating
Problem: Component styles don’t update when theme changes
Solution: Use useThemedStyles
instead of static styles
// ❌ Static styles won't updateconst styles = StyleSheet.create({...});// ✅ Dynamic styles update with themeconst styles = useThemedStyles(createStyles);
Performance Issues
Problem: App feels sluggish with theme changes Solution: Implement proper memoization and lazy loading
// Memoize expensive operationsconst memoizedStyles = useThemedStyles(createStyles);const memoizedData = useMemo(() => processData(data), [data]);
TypeScript Errors
Problem: TypeScript complains about theme types Solution: Update type definitions and use proper imports
import { Theme } from 'rnc-theme';const createStyles = (theme: Theme) => StyleSheet.create({ // Your styles});
Explore Components
Dive deeper into the Component Library to discover all available components and their props.
Customize Themes
Learn about Theme Customization to match your brand colors and spacing.
Add More Screens
Build out your app with consistent theming using the patterns you’ve learned.
Optimize Performance
Check out Performance Tips for production-ready optimizations.