A personal Expo starter kit with a lightweight design system, Expo Router, Zustand state, Storybook, and Jest tests. Designed as a clean, opinionated base for future apps.
- Expo SDK 54 + Expo Router
- TypeScript
- Zustand (with AsyncStorage persistence)
- Light / Dark / System theming
- i18n via i18next and react-i18next
- Storybook for React Native
- Jest + @testing-library/react-native
- Prettier + Husky
- React query
- Theme tokens: spacing, radii, sizes
- Typography variants
- Components:
- Text
- Button
- Input
- Dropdown
- Card
- Divider
- Spinner
- Layout primitives:
- AppLayout
- Screen
- Stack
- Row
- Section
npm installnpm run startPlatform shortcuts:
npm run android
npm run ios
npm run webIf you encounter adb reverse or device offline issues:
npx expo start --tunnelStorybook runs the app behind a feature flag.
npm run storybookThis sets:
EXPO_PUBLIC_STORYBOOK_ENABLED=true
Use this flag to conditionally render Storybook instead of the normal Expo Router entry.
Watch mode:
npm testCI mode:
npm run test:cinpm run format
npm run format:checkTheme mode is stored in Zustand and persisted to AsyncStorage.
Available modes:
- system
- light
- dark
Usage:
import { useTheme } from '../theme/useTheme';
const { theme, resolved } = useTheme();Examples:
- theme.colors.bg
- theme.spacing[4]
- theme.radii.md
- theme.typography.body
- No raw spacing values in features (use theme.spacing)
- No ad-hoc font sizes (use Text variants)
- AppLayout owns background, safe area, and horizontal padding
- Stack and Row own spacing (avoid margin chains)
Components are re-exported from components/index.ts:
import {
Button,
Card,
Divider,
Dropdown,
Input,
Spinner,
Text,
} from '../components';Layout helpers:
import { AppLayout } from '../layout/AppLayout';
import { Screen } from '../layout/Screen';
import { Stack } from '../layout/Stack';
import { Row } from '../layout/Row';
import { Section } from '../layout/Section';app/ # expo-router routes
components/ # UI components
layout/ # layout primitives
theme/ # tokens and useTheme
state/ # zustand stores
storybook-app/ # storybook entry
assets/ # fonts and images
i18n/ # translations
api/ # react query api folder
queries/ # react query queries folder
- Copy or scaffold from this repo
- Update app name and identifiers
- Remove or adapt the playground screen
- Build your first real feature
- Extract new components only when patterns repeat
This template includes a minimal eas.json for convenience.
Profiles:
development– dev-client buildspreview– internal distributionproduction– store builds (no auto-submit)
Before using EAS:
- Update app identifiers (bundle ID / package name)
- Configure credentials via
eas build - Adjust profiles as needed for your app
Personal starter kit — free to use across personal projects.