Get up and running with React Native Starter in under 5 minutes.
Before you begin, ensure you have:
- Node.js 24 (pinned in
.nvmrc; runnvm use) or 22.13+, matching React Native 0.86's supported range - Download - npm - comes with Node.js; the repository ships a
package-lock.json - Expo Go app (optional) - For testing on physical devices
- Xcode 26.4 or later - required by Expo SDK 57 for native iOS builds; verify
with
xcodebuild -versionbefore running a native build. Download from App Store - iOS Simulator - Included with Xcode
Expo SDK 57 supports iOS 16.4 and later. An older Xcode can still provide a
simulator, but it cannot compile this SDK's native iOS project. With an older
Xcode you can still run the app in Expo Go on the simulator (npm start, then
press i); for a native iOS build (npx expo run:ios), upgrade Xcode first.
- Android Studio - Download
- Android SDK - Installed via Android Studio
- Android Emulator - Set up via Android Studio
- JDK 17 - required for native Android builds (
npx expo run:android). PointJAVA_HOMEat a JDK 17 install. The JDK 25 bundled with recent Android Studio releases fails the native CMake configure step ("A restricted method in java.lang.System has been called"). Expo Go doesn't need a JDK.
- Clone or fork the repository:
git clone https://github.com/koniz-dev/react-native-starter.git
cd react-native-starter- Install dependencies:
npm cinpm ci installs exactly what package-lock.json records. Use npx expo install <package> to add Expo-related packages so their versions match SDK 57.
- Set up environment variables (required):
cp .env.example .env.env.example sets EXPO_PUBLIC_USE_DEMO_BACKENDS=true, so the starter uses
JSONPlaceholder for its todos example and DummyJSON for its authentication demo
(username emilys, password emilyspass). Without a .env, the app opens on a
Configuration error screen that lists the missing variables.
To use your own backends, set EXPO_PUBLIC_API_URL and EXPO_PUBLIC_AUTH_API_URL
and turn the demo flag off; then adapt the request and response mapping in
services/auth.ts to your backend's authentication contract. See
Environment Variables for every variable and its rules.
npm startThis starts the Expo development server. You'll see a QR code and options to:
- Press
a- Open on Android emulator/device - Press
i- Open on iOS simulator (macOS only) - Press
w- Open in web browser - Scan QR code - Open in Expo Go app on your device
# Android
npm run android
# iOS (macOS only)
npm run ios
# Web
npm run webreact-native-starter/
├── app/ # Expo Router screens (file-based routing)
│ ├── (tabs)/ # Tab navigation screens
│ └── _layout.tsx # Root layout with theme provider
├── components/ # Reusable UI components
│ ├── ErrorBoundary.tsx
│ └── LoadingScreen.tsx
├── hooks/ # Custom React hooks
│ └── useFetch.ts # Data fetching hook
├── services/ # API & storage services
│ ├── api.ts # Axios client with interceptors
│ └── storage.ts # AsyncStorage wrapper
├── types/ # TypeScript type definitions
│ └── api.ts # API response types
├── constants/ # App constants
│ ├── Colors.ts # Color definitions
│ └── Theme.ts # React Native Paper theme
├── assets/ # Images, fonts, static files
└── docs/ # Documentation
app/- All screens go here. Files automatically become routes (Expo Router).components/- Reusable UI components used across screens.hooks/- Custom React hooks for shared logic (e.g.,useFetch).services/- API client and storage utilities.constants/- App-wide constants like colors and theme config.types/- TypeScript interfaces and types.
Everything below is configuration; no source code changes are needed to ship your own app identity and backends.
| What | Where |
|---|---|
| App name, slug, URL scheme, bundle/package ID, marketing version | APP block at the top of app.config.ts |
Store build number (iOS buildNumber, Android versionCode) |
APP_BUILD_NUMBER environment variable at build time (default 1) |
| App icon, Android adaptive icon, splash image, favicon | Replace the files in assets/ (see Splash Screen and App Icon) |
| Splash and adaptive-icon background colors | APP.splashBackground and APP.adaptiveIconBackground in app.config.ts |
| API and auth backends | EXPO_PUBLIC_API_URL, EXPO_PUBLIC_AUTH_API_URL in .env / build profile; set EXPO_PUBLIC_USE_DEMO_BACKENDS=false (see Environment Variables) |
| Extra hosts allowed to receive the auth token | EXPO_PUBLIC_API_TRUSTED_ORIGINS |
| Per-variant build settings and environment | eas.json build profiles |
APP_VARIANT selects one of three variants. Each has its own name, bundle ID, and
scheme, so they install side by side:
| Variant | Name | Bundle/package ID | Scheme | EXPO_PUBLIC_APP_ENV |
|---|---|---|---|---|
development (default) |
RN Starter (Dev) |
com.example.rnstarter.dev |
rnstarter-dev |
development |
preview |
RN Starter (Preview) |
com.example.rnstarter.preview |
rnstarter-preview |
preview |
production |
RN Starter |
com.example.rnstarter |
rnstarter |
production |
npm startruns the development variant;npm run start:previewandnpm run start:productionrun the others (production without dev mode).npm run prebuild:<variant>generates the nativeandroid/andios/projects for a variant (both directories are gitignored), which you can build locally with Android Studio / Xcode ornpx expo run:android|ios.npm run config:printshows the resolved configuration; prefix it withAPP_VARIANT=previewto inspect another variant.eas.jsondefines matchingdevelopment,preview, andproductionbuild profiles for EAS Build. Using EAS requires your own Expo account; nothing else in the starter does.- Preview and production builds use
httpsURLs only; set the backend URLs in the build profile'senvor witheas env:create, because.envis not committed.
The scripts use POSIX VAR=value command syntax (macOS, Linux, WSL). On Windows
without WSL, set the variables in your shell first.
Now that you're running, here's where to start coding:
- Explore existing screens - Check
app/(tabs)/index.tsxto see example usage - Add a new screen - See How to Add a New Screen
- Customize theme - Edit
constants/Theme.tsandconstants/Colors.ts - Connect to your API - Update
EXPO_PUBLIC_API_URLin.envand modifyservices/api.ts - Read the guides - Check out How-To Guides for common tasks
npm start- Start Expo dev server (development variant)npm run start:preview/npm run start:production- Start another variantnpm run prebuild:development|preview|production- Generate native projects for a variantnpm run config:print- Print the resolved app configurationnpm run android- Run on Android emulator/devicenpm run ios- Run on iOS simulator/devicenpm run web- Run in web browsernpm run lint- Check code qualitynpm run lint:fix- Fix linting issues automaticallynpm run format- Format code with Prettiernpm test- Run tests
Port already in use:
# Kill process on port 8081 (default Expo port)
npx kill-port 8081
npm startMetro bundler cache issues:
npm start -- --clearNode modules issues:
rm -rf node_modules
npm ci
npx expo-doctorKeep package-lock.json; regenerating it can pull peer versions that don't match
the Expo SDK.
iOS build issues (macOS):
cd ios
pod install
cd ..
npm run iosThis starter comes with:
- ✅ React Native Paper - Material Design 3 components
- ✅ Dark/Light mode - Automatic system preference detection
- ✅ API client - Axios with interceptors for auth & errors
- ✅ Storage service - AsyncStorage wrapper with TypeScript
- ✅ Custom hooks -
useFetchfor data fetching - ✅ Error boundary - Global error handling
- ✅ Loading states - Built-in loading screen component
- ✅ Authentication example - Complete login flow with token management
- ✅ TypeScript - Full type safety
- ✅ ESLint + Prettier - Code quality tools
- ✅ Example screens - See it in action
- How-To Guides - Common development tasks
- Code Conventions - Project standards and best practices
- API and Storage - Backend integration guide
- UI Library Guide - React Native Paper components
- Expo Documentation - Official Expo docs
- Check the How-To Guides for common questions
- Review Code Conventions for project standards
- Visit Expo Discord for community support