Starter Architecture
Use this starter for most solo-dev Expo apps.
app/
_layout.tsx
(tabs)/
_layout.tsx
index.tsx
settings.tsx
item/[id].tsx
+not-found.tsx
src/
api/
client.ts
items.ts
hooks/
useItems.ts
stores/
settingsStore.ts
components/
ui/
item/
providers/
AppProviders.tsx
types/
api.ts
assets/
app.json or app.config.ts
eas.json
jest.config.js
Layer Rules
| Layer | Owns | Keep out |
|---|---|---|
app/ | Routes, layouts, route-specific screen composition | API client internals, persistent store implementation |
src/api/ | HTTP client, endpoint functions, DTO conversion | React components and hooks |
src/hooks/ | Server-state hooks, route-ready data functions | Raw Axios calls in screens |
src/stores/ | Client-only state such as settings, player state, drafts | Server cache that belongs in TanStack Query |
src/components/ | Reusable UI and feature components | Navigation side effects that belong in routes |
src/providers/ | Query client, safe area, theme, gesture, auth providers | Screen-specific data fetching |
Minimal Root Layout
import { Stack } from 'expo-router';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
export default function RootLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<QueryClientProvider client={queryClient}>
<Stack />
</QueryClientProvider>
</GestureHandlerRootView>
);
}
Start Smaller Than You Think
Include in v1:
- Expo Router.
- TypeScript.
- One API client module.
- One server-state pattern.
- One client-state store only if needed.
- Jest and one route/screen test.
- EAS profiles for development, preview, and production.
Defer until there is pressure:
- Custom native modules.
- Multiple app variants.
- Background jobs.
- Deep local-first sync.
- Custom config plugins.
- Complex navigation state outside Expo Router.
Gotcha: Do not put tests inside
app/. Expo Router treats files underapp/as route inputs. Keep tests in__tests__/, colocated outsideapp/, or undersrc/.