create-expo-app Quickstart
Scaffold a new Expo project with the correct template, an explicit SDK 57 pin, and a verification pass so your team starts on React Native 0.86 - not an accidental older SDK.
Search across all documentation pages
Scaffold a new Expo project with the correct template, an explicit SDK 57 pin, and a verification pass so your team starts on React Native 0.86 - not an accidental older SDK.
Quick-reference recipe card - copy-paste ready.
# Pin SDK 57 explicitly (recommended for new production apps)
npx create-expo-app@latest MyApp --template default@sdk-57
cd MyApp
# Confirm the SDK pin before writing features
node -e "const p=require('./package.json'); console.log({expo:p.dependencies.expo, rn:p.dependencies['react-native']})"
npx expo-doctor
npx expo startWhen to reach for this:
default, tabs, blank, or bare-minimum before the repo grows roots.create-expo-app@latest changed its default template.#!/usr/bin/env bash
# scripts/scaffold-team-app.sh - reproducible SDK 57 project for your org
set -euo pipefail
APP_NAME="${1:-TeamMobile}"
TEMPLATE="${2:-default@sdk-57}" # tabs@sdk-57 | blank-typescript@sdk-57 | bare-minimum@sdk-57
npx create-expo-app@latest "$APP_NAME" \
--template "$TEMPLATE" \
--yes
cd "$APP_NAME"
# Lockfile + git from day one
git init
git add .
git commit -m "chore: scaffold $APP_NAME ($TEMPLATE)"
# Sanity checks every new repo should pass
npx expo-doctor
npx tsc --noEmit
echo "✅ $APP_NAME ready - run: cd $APP_NAME && npx expo start"After the script finishes, open the project and confirm package.json dependencies:
{
"dependencies": {
"expo": "~57.0.4",
"react": "19.2.3",
"react-native": "0.86.0"
},
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
}
}What this demonstrates:
--template default@sdk-57 so the scaffold matches your stack manifest, not whatever @latest defaults to during an SDK transition.--yes for CI-friendly, non-interactive project creation.expo-doctor as the first gate after scaffold - catches incompatible native module versions early.create-expo-app downloads a versioned template from the Expo monorepo, writes package.json, installs dependencies, and generates starter source (Expo Router layout for default/tabs).@sdk-57 suffix on a template name pins the Expo SDK major at scaffold time - the template's package.json resolves expo to ~57.0.4 and matching react-native / react peers.npx expo install <pkg> (used later) reads the pinned expo version and installs compatible native module versions - but only if the base expo pin is correct first.expo-doctor compares your dependency graph against the SDK 57 compatibility database and flags mismatches before they surface as obscure Metro or native build errors.| Template | Ships | Choose when |
|---|---|---|
default@sdk-57 | Expo Router, TypeScript, tab/stack starter, recommended scripts | Most new apps - the team default |
tabs@sdk-57 | File-based routing focused starter (similar to default) | You want routing-first structure without extra boilerplate stripped |
blank@sdk-57 / blank-typescript@sdk-57 | Minimal JS/TS, no navigation wired | Library spikes, brownfield experiments, teaching RN primitives |
bare-minimum@sdk-57 | Blank + android/ and ios/ via npx expo prebuild | You need native directories immediately (custom native code day one) |
# Examples - always include the SDK suffix for new SDK 57 work
npx create-expo-app@latest Shop --template tabs@sdk-57
npx create-expo-app@latest Spike --template blank-typescript@sdk-57
npx create-expo-app@latest NativeDay1 --template bare-minimum@sdk-57| Check | Command / location | Expected for SDK 57 |
|---|---|---|
expo package version | package.json → dependencies.expo | ~57.0.4 |
| React Native peer | package.json → dependencies.react-native | 0.86.0 |
| React peer | package.json → dependencies.react | 19.2.3 |
| Doctor pass | npx expo-doctor | No errors (warnings reviewed) |
| Resolved config | npx expo config --type public | sdkVersion / plugins align with 57 |
| Flag | Effect |
|---|---|
--template <name>@sdk-57 | Selects starter + SDK major |
--yes | Accepts defaults (name from folder, install deps) |
--no-install | Skips npm install / CocoaPods - useful in CI that installs separately |
--example <name> | Clones an example from expo/examples instead of a core template |
--no-agents-md | Skips AI agent context files (AGENTS.md, etc.) |
// App.tsx - blank-typescript template entry (no Router)
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<Text>SDK 57 app booted.</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: "center", justifyContent: "center" },
});The default@sdk-57 template uses Expo Router (app/_layout.tsx) instead - prefer that for multi-screen apps.
@sdk-57 - During the SDK 57 transition, npx create-expo-app@latest without --template may create an SDK 54 project. Fix: Always pass --template default@sdk-57 (or your chosen template with the SDK suffix).bare-minimum by default - It runs prebuild immediately, committing android/ and ios/. Teams on managed workflow lose CNG simplicity. Fix: Start with default@sdk-57; run npx expo prebuild only when native dirs are required.expo-doctor after scaffold - Version skew (e.g. expo-camera built for SDK 56) compiles but crashes at runtime. Fix: Run npx expo-doctor and npx expo install --fix before feature work.yarn install leaves duplicate lockfiles and EAS may pick the wrong one. Fix: Stick to one manager; delete the other lockfile if migrating.slug - app.json / app.config slug stays at scaffold value; deep links and EAS project URLs break. Fix: Update slug, name, and bundle identifiers together in app config.node_modules or omitting the lockfile - Reproducible installs fail across machines and EAS. Fix: Commit package-lock.json / yarn.lock / pnpm-lock.yaml; keep node_modules gitignored.| Alternative | Use When | Don't Use When |
|---|---|---|
create-expo-app with @sdk-57 template | New Expo apps; team wants official starters | You are adding RN to an existing native app (brownfield) |
npx @react-native-community/cli init | Pure RN without Expo tooling | You want EAS, Expo modules, and managed upgrades |
expo/examples via --example | Learning a specific integration (Router, SQLite, etc.) | Production app scaffold - examples are demos, not product templates |
| Monorepo generators (Nx, Turborepo) | Multiple apps sharing packages | A single standalone app - extra complexity upfront |
| Fork an internal template repo | Org-wide lint, CI, and design tokens baked in | One-off prototypes where official templates are faster |
create-expo-app is Expo's project generator. It copies a versioned template, installs dependencies, and wires scripts (expo start, platform targets). It is the recommended way to start SDK 57 projects.
During the SDK 57 rollout, create-expo-app@latest without a template may still scaffold SDK 54 for Expo Go compatibility on physical devices. New production work should pin @sdk-57 explicitly so package.json resolves expo ~57.0.4.
default@sdk-57. It includes Expo Router, TypeScript, and the standard Expo CLI scripts. Use blank-typescript@sdk-57 for minimal spikes and bare-minimum@sdk-57 only when you need native directories immediately.
node -e "console.log(require('./package.json').dependencies.expo)"
npx expo-doctorExpect ~57.0.4 and a clean doctor report.
It validates that expo, react-native, and installed Expo modules match the SDK compatibility matrix. Run it after every scaffold and after adding native dependencies.
Yes. Pass --yes and the app name:
npx create-expo-app@latest MyApp --template default@sdk-57 --yesBoth target multi-screen apps with Expo Router and TypeScript. default is the general-purpose starter; tabs emphasizes tab navigation structure. For most teams they are interchangeable - pick one and standardize.
When you need android/ and ios/ directories on day one - custom native modules, existing CI that compiles native projects, or brownfield integration. Otherwise start managed and run npx expo prebuild later.
Expo Go on the App Store tracks one SDK at a time. An SDK 57 project requires a compatible Expo Go build. On iOS devices you cannot sideload older Expo Go versions - use a simulator, download a matching build from expo.dev/go, or create a development build.
cd MyApp
npx expo startPress i for iOS Simulator, a for Android emulator, or scan the QR code with Expo Go / a development build.
All are supported. create-expo-app configures package-manager-specific settings (e.g. Yarn PnP nodeLinker: node-modules). Pick one per repo and commit the matching lockfile - EAS detects it automatically.
Skips installing JavaScript dependencies (and CocoaPods for bare-minimum). Useful when CI runs npm ci in a later step with cached registries.
Yes. --example with-router pulls from expo/examples. Examples teach specific features; they are not a substitute for default@sdk-57 when you want the maintained production starter.
Always use Expo's installer so versions match SDK 57:
npx expo install expo-cameraNever npm install expo-camera@latest without checking compatibility.
Commit source, app.json / app.config, package.json, lockfile, tsconfig.json, and assets. Do not commit node_modules, .expo/, or local .env*.local files with secrets.
Stack versions: This page was written for React 19.2.3, React Native 0.86.0, and Expo SDK 57 (
expo~57.0.4).
Reviewed by Chris St. John·Last updated Jul 16, 2026