Developer Handoff: Frontend
You're inheriting a frontend-only React Native app generated by RapidNative. It's a clean Expo + Expo Router scaffold with NativeWind theming and light/dark mode. No backend, no database, no auth wired up by default. Bring your own data layer when you're ready.
This guide gets you from clone to running in about five minutes.
If your project has a
src/db/folder, a.envwithEXPO_PUBLIC_ADAPTER_TYPE, or auth screens underapp/(auth)/, you have a fullstack project. Use the Developer Handoff: Fullstack guide instead.
Mental model in 60 seconds
Standard Expo + Expo Router app. Theming is CSS-variable-driven: theme.ts exports lightTheme and darkTheme as bundles of CSS variables (via NativeWind's vars()), and ThemeProvider applies the active bundle through useColorScheme(). tailwind.config.js then resolves Tailwind classes like bg-background and text-foreground to those CSS variables.
There's no global state library, no auth, no API client. The data layer is yours to choose.
The stack
| Layer | Technology |
|---|---|
| Framework | Expo 54 + React Native 0.81 + React 19 |
| Routing | Expo Router 6 (file-based) |
| Language | TypeScript (extends expo/tsconfig.base, not strict) |
| Styling | NativeWind 4 + Tailwind CSS 3.4 |
| Theming | theme.ts (NativeWind vars) + ThemeProvider |
| Safe areas | react-native-safe-area-context |
| Navigation | @react-navigation/bottom-tabs + native + elements |
| Icons | lucide-react-native |
| Storage | @react-native-async-storage/async-storage |
| Variant helpers | lib/cva.ts (custom) + tailwind-variants |
No database. No auth. No state library. No API client.
Folder structure
1project-root/
2├── app/ # Expo Router pages (file-based routing)
3│ └── _layout.tsx # Wraps children in ThemeProvider + SafeAreaProvider
4├── components/
5│ ├── ThemeProvider.tsx # Light/dark switching + applies CSS vars
6│ └── ThemeToggle.tsx # Ready-made theme switcher button
7├── lib/
8│ └── cva.ts # Custom class-variance-authority style helper
9├── theme.ts # lightTheme / darkTheme as vars() bundles + fonts
10├── theme.md # Theming guide
11├── layout.md # Layout / screen structure guide
12├── tailwind.config.js # Maps CSS vars to Tailwind color classes
13├── global.css # Tailwind base/components/utilities directives
14├── nativewind-env.d.ts # NativeWind TypeScript augmentation
15├── app.json # Expo config
16├── babel.config.js
17├── metro.config.js
18├── tsconfig.json # `@/*` path alias to root
19├── eslint.config.js
20├── rapidnative.json # Internal RapidNative metadata (safe to ignore)
21├── package.json
22├── README.md # Default Expo template README
23└── .claude/ # AI agent settings used during generationA few notes:
theme.mdandlayout.mdare part of the scaffold. They walk through theming rules and the screen-structure conventions the AI follows. Worth a five-minute skim.global.cssis intentionally minimal, just@tailwind base/components/utilities. The actual color values are not in CSS; they're injected at runtime byThemeProviderfromtheme.ts'svars()exports.@/*path alias points to project root, configured intsconfig.jsonand matched inbabel.config.jsviababel-plugin-module-resolver. Imports like@/components/ThemeProviderwork out of the box..claude/andrapidnative.jsonare RapidNative metadata used during AI-assisted generation.
Installation
Prerequisites
- Node.js 20+
- Expo CLI (installed globally or via
npx) - iOS Simulator (Xcode) or Android Emulator (Android Studio), or the Expo Go app on a physical device
Install dependencies
1npm installNo .env setup needed. There's no backend to point at.
Quick start
1# Start the Expo dev server
2npm start
3
4# Open the app
5# Press 'i' for iOS Simulator
6# Press 'a' for Android Emulator
7# Or scan the QR code with Expo Go on your phoneTheming
The scaffold ships with a CSS-variable-driven theme. Both light and dark themes live in theme.ts as vars(...) exports:
1// theme.ts (excerpt)
2import { vars } from 'nativewind';
3
4export const lightTheme = vars({
5 '--background': '255 255 255', // RGB space-separated, NOT hex
6 '--foreground': '23 23 23',
7 '--primary': '...',
8 // ...
9});
10
11export const darkTheme = vars({ /* ... */ });ThemeProvider reads useColorScheme() from NativeWind, picks the right bundle, and applies the CSS variables. On web it sets them on document.documentElement so RN Modal portals (which mount outside the wrapper View) still inherit theme values. tailwind.config.js then maps those CSS variables to Tailwind classes:
1// tailwind.config.js (excerpt)
2colors: {
3 background: 'rgb(var(--background) / <alpha-value>)',
4 foreground: 'rgb(var(--foreground) / <alpha-value>)',
5 // ...
6}So in components you write bg-background, text-foreground, bg-primary, etc., and they automatically follow the active theme.
To rebrand:
- Open
theme.ts. - Replace the RGB space-separated values (e.g.
'255 255 255') for the tokens you want to change. Don't use hex.tailwind.config.jsdefines colors asrgb(var(--token) / <alpha-value>), so opacity utilities likebg-foo/50only work when the channels are separated. - Restart Metro. NativeWind picks up the new values.
theme.md in the scaffold walks through the full token list and how to add new tokens. ThemeToggle.tsx is a ready-made button that flips between light and dark.
The scaffold also pre-loads Inter and JetBrains Mono via expo-font (configured in theme.ts and loaded in _layout.tsx). Use Tailwind classes like font-heading, font-body, font-mono, or the more direct font-inter-semibold / font-jetbrains etc.
Layout & theming guidelines
layout.md and theme.md in the scaffold are guideline documents. layout.md covers screen structure and layout conventions, theme.md covers theming tokens and how the color system works. They're written primarily so RapidNative's AI agents follow consistent patterns during generation, and they double as a quick reference for any developer inheriting the project. Skim both before making structural or visual changes.
Variant helpers
When you write variant-driven components (multiple sizes, intents, states on the same primitive), two helpers ship with the project:
lib/cva.ts: a small custom helper with aclass-variance-authority-style API.tailwind-variants: the full third-party library, also installed.
Pick whichever you prefer. Stay consistent within a feature so future readers (human or AI) don't have to context-switch.
Adding a backend
The scaffold ships without one by design. When you're ready to plug in data:
- Quickest swap to the same stack RapidNative's fullstack template uses: install Vibecode DB, point it at Supabase or PocketBase, and access the client via a context provider. The Fullstack Handoff covers this stack in detail (folder structure, the three adapters, schema 3-file sync rule).
- Bring your own: any data layer works. TanStack Query + your REST API, Apollo + GraphQL, the Supabase JS SDK, Firebase, etc. The frontend isn't coupled to anything.
Going to production
The scaffold does not ship eas.json. To configure EAS for the first time:
1# Generate eas.json with default profiles
2npx eas build:configure
3
4# Build for production (iOS + Android)
5eas build --platform all
6
7# Submit to App Store / Play Store
8eas submit --platform allBefore shipping:
- Configure the generated
eas.jsonprofiles for your team's signing identity. - Add app store metadata, icons, and screenshots.
- Wire up your data layer if you haven't yet (see above).
If your team would rather skip the certificates / store listings / submission grind, RapidNative offers an end-to-end deployment service starting at $499. See rapidnative.com/deploy.
Where to get help
theme.mdin the scaffold: full theming reference (color tokens, dark mode, fonts, radius).layout.mdin the scaffold: screen structure, spacing, safe area, ScrollView patterns..claude/directory: AI agent settings used during generation. Useful if you continue AI-assisted development on the project.- Expo & React Native: standard docs apply, no overrides.
- Expo Router: docs.expo.dev/router
- NativeWind: nativewind.dev (especially the theming guide for how
vars()works) tailwind-variants: tailwind-variants.org
If something doesn't make sense after reading this, the answer is almost certainly in theme.md, layout.md, or one of the other markdown guides shipped inside the project.