How we structure a React Native codebase
New projects start with Expo and TypeScript, using Expo Router for file-based navigation and development builds so custom native code is always possible. Code is organized by feature rather than by file type, with shared folders for the design system, API client and utilities. When a web app exists, we place shared types, validation and business logic in packages within a monorepo so both apps use the same rules.
Server state is handled with TanStack Query, local state with lightweight stores such as Zustand, and native capabilities through Expo modules or custom modules written with the Expo Modules API in Swift and Kotlin. EAS Build produces signed binaries in CI, and EAS Update channels deliver JavaScript fixes to staging and production separately.
- Strict TypeScript with an API client generated from the backend schema.
- Feature folders with screens, hooks and tests kept together.
- Unit and component tests with Jest and React Native Testing Library.
- End-to-end flows tested with Maestro or Detox on real devices.
- Environment configuration through app config, never hardcoded keys.
- Error monitoring with Sentry or a similar service from the first build.
- Feature flags for risky changes that may need a quick switch off.


