Rn bootstrap
Scaffold a new Expo + React Native app from a PROJECT.md + PRD.md + DESIGN.md using the opinionated stack (Expo Router, TypeScript, NativeWind v4, Zustand, TanStack Query, Reanimated, expo-image, FlashList). Reads .workflow/meta.json with stack.framework="expo-rn" and phase in {prd_drafted, design_extracted}. Produces a running Expo app at the project root, sets phase to "scaffolded". Always idempotent: re-running detects existing files and skips. Use when dev-flow routes here from prd_drafted+expo-rn, or the user says "scaffolda app expo from PRD", "create RN app from this PRD/DESIGN", "bootstrap expo app". Not for: adding screens (rn-add-screen, Wave 2), modules (rn-module-add, Wave 3), Next.js scaffolding (design-md-to-app — different stack).From its SKILL.md
npx -y skills add lukedj78/dev-flow --skill rn-bootstrapAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 4 commands, including `scripts/init-expo-app.sh <project-root> <app-name>` and 3 more.
SKILL.md
8.6 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
rn-bootstrap — scaffold Expo + RN from PRD/DESIGN
Contract
See references/contracts.md (vendored from dev-flow). Key facts:
- Reads
<project-root>/.workflow/meta.json#stack.framework— must be"expo-rn". - Reads
<project-root>/{PROJECT.md, PRD.md, DESIGN.md}. DESIGN.md is required for tokens; if absent, uses defaults fromreferences/stack-defaults.md. - Writes the app to
<project-root>/(the same directory). - Sets
meta.json#phase = "scaffolded"on success. - Always idempotent: re-running detects existing
package.json+app/and exits 0.
When this skill applies
- Orchestrator routes here from
dev-flowwhenmeta.json#stack.framework == "expo-rn"andmeta.json#phase ∈ {prd_drafted, design_extracted}. - User says: "scaffolda app expo", "create RN app from PRD".
Knowledge dependencies (read these first)
rn-fundamentals/SKILL.md— confirms Expo SDK + New Architecture + TypeScript + npm.rn-styling/references/nativewind-setup.md— the 7-step NativeWind setup (this skill automates it).rn-expo-router/references/concepts.md— folder layout forapp/.
Workflow
Step 1 — Verify preconditions
Read <project-root>/.workflow/meta.json. Abort with a clear message if:
- file missing → "Run
dev-flow init_workflow.pyfirst." stack.framework != "expo-rn"→ "This skill is for stack.framework=expo-rn. For Next.js use design-md-to-app."phase ∉ {prd_drafted, design_extracted}→ "Expected phase prd_drafted or design_extracted, got X."
If package.json + app/ already exist at project root: print "Already bootstrapped, nothing to do", set phase to scaffolded if not already, exit 0.
Step 2 — Run create-expo-app
Run scripts/init-expo-app.sh <project-root> <app-name>. The app name comes from meta.json#project_name (or PROJECT.md title).
Step 3 — Install opinionated stack
Run scripts/install-stack.sh <project-root>. Installs NativeWind v4 (with Tailwind 3.4 pin), Zustand, TanStack Query, Reanimated, RNGH, expo-image, FlashList.
Step 4 — Wire NativeWind from DESIGN.md tokens
Run npx tsx scripts/wire-nativewind.ts <project-root>. Generates tailwind.config.js, global.css, babel.config.js, metro.config.js. Reads tokens from a fenced ```json tokens block in DESIGN.md (accepts LF + CRLF line endings).
Step 5 — Generate folder structure + boilerplate
Create (only if absent — idempotent):
app/_layout.tsx— Stack root, imports../global.css, renders<Stack />.app/index.tsx— hello-world screen using NativeWind classes (wraps inSafeAreaViewfromreact-native-safe-area-context).components/,lib/,store/,types/,assets/— empty dirs with.gitkeep..env.example— empty stub withEXPO_PUBLIC_API_URL=.tsconfig.json— extendexpo/tsconfig.base, addpathsfor@/*.
Also patch app.json:
expo.scheme— set to a kebab-case ofmeta.json#project_name.expo.experiments.typedRoutes—true.expo.newArchEnabled—true.expo.plugins— add"expo-router".
Step 6 — Verify (scripts/verify.ts)
Run npx tsx scripts/verify.ts <project-root>. If exit code != 0, do NOT bump phase. Report failures from references/post-bootstrap-checklist.md.
Step 7 — Update meta.json + commit
Update meta.json:
stack: merge{ framework: "expo-rn", ui: "nativewind", auth: null, db: null, payments: null, deploy: null }(existing keys preserved if already set).stack_config: merge{ expo_sdk: "<X>", state_lib: "zustand", data_lib: "tanstack-query" }.phase: set to"scaffolded".history: append{ skill: "rn-bootstrap", ran_at: <iso>, outputs: ["package.json", "app/", "tailwind.config.js", ...], phase_before: <prev>, phase_after: "scaffolded" }.
If <project-root> is a git repo, create a commit: chore: scaffold Expo + RN app via rn-bootstrap.
Updating meta.json (recommended pattern)
When this skill modifies state (artifact written, phase advanced, history appended), use the canonical script when available:
# Wherever dev-flow is installed (e.g. ~/.claude/skills/dev-flow/), invoke:
python3 .../dev-flow/scripts/update_meta.py <project-root> record-artifact \
--path <relative-path> --produced-by '<this-skill-name>' [--derived-from <p1> <p2> ...]
python3 .../dev-flow/scripts/update_meta.py <project-root> set-phase <new_phase>
python3 .../dev-flow/scripts/update_meta.py <project-root> append-history \
--skill '<this-skill-name>' --inputs '{...}' --outputs '{...}' --phase-after <new_phase>
The script enforces phase monotonicity, normalizes legacy kebab-case aliases (e.g. module-added → module_added), and writes the canonical sha256 + timestamp into meta.json#artifacts. Fall back to direct JSON editing only if the script is not on PATH (and warn the user).
Folder structure rules (canonical — Expo Router hybrid)
Non-negotiable Expo Router constraint: app/ is file-based routing only. Unlike Next.js App Router, Expo Router has no private-folder convention — there is no _-prefix skip rule, so every file placed under app/ (aside from reserved names like _layout.tsx, +not-found.tsx) becomes a real route. A previous revision of this skeleton put _components/ folders inside app/, copied from the Next.js convention — that was wrong for Expo (it creates ghost routes) and is corrected below. [VERIFY] against the installed expo-router version: there's an open upstream request for an underscore-skip convention; until it ships, assume app/ has zero tolerance for non-route files.
This skill scaffolds the canonical RN structure, hybrid model (spec: docs/superpowers/specs/2026-06-06-folder-structure-refactor.md, adapted for Expo Router):
app/ # ROUTES ONLY — no components, no hooks, no utils
├── (auth)/ # opt-in based on stack.route_groups
│ ├── _layout.tsx
│ └── sign-in.tsx
├── (app)/
│ ├── _layout.tsx # redirect to (auth) if !session
│ ├── (tabs)/ # opt-in based on stack.route_groups
│ │ ├── _layout.tsx
│ │ ├── feed/
│ │ └── profile/
│ └── settings.tsx
└── _layout.tsx # root: GestureHandlerRootView + ThemeProvider
components/ # ALL non-route UI lives here, outside app/
├── ui/ # NativeWind primitives
├── theme/ # ThemeProvider, useThemeColor
├── shared/ # L2 per dominio (created empty)
└── <feature>/ # L0/L1 screen-private components (e.g. components/feed/, components/profile/)
# created on demand by rn-add-screen, not scaffolded empty here
lib/ # api, supabase, secure-store, utils
store/ # Zustand cross-feature (auth-store, app-preferences)
hooks/ # RN-specific (useColorScheme, useKeyboard)
assets/ # images/, fonts/
No src/ prefix: app/, components/, lib/ etc. stay at the project root — matches the default create-expo-app templates (which don't use src/) and keeps rn-add-screen / promote-component consistent with this scaffold.
Read meta.json#stack.route_groups to decide which route groups to scaffold. Empty array → flat routing (rare for mobile).
Components follow Rule of Three for promotion (L0 → L1 → L2), targeting components/<feature>/ (L0/L1) and components/shared/<dominio>/ (L2) — never app/<route>/_components/. See rn-add-screen for screen-level details and promote-component for the promotion mechanics.
Sources
- Course: codewithbeto.dev/rnCourse — free lessons 5-6 (Creating Your First App, Project Structure).
- Official: https://docs.expo.dev/get-started/create-a-project/
- Official: https://www.nativewind.dev/v4/getting-started/expo-router
What ships with it: 10 files
59.6 KB alongside SKILL.md, 4 of them executable
references/
- contracts.md28.9 KB
- .gitkeep0 B
- i18n-rn.md12.6 KB
- post-bootstrap-checklist.md2.3 KB
- stack-defaults.md2.5 KB
scripts/
- .gitkeep0 B
- init-expo-app.shruns3.3 KB
- install-stack.shruns1.8 KB
- verify.tsruns3.7 KB
- wire-nativewind.tsruns4.4 KB