expo-project-bootstrap
Creates a new Expo app from empty - SDK 57 stack, Expo Router, root configs, gates, variants, icons - proven by a checker.
Skill by zakariaf
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/zakariaf-expo-project-bootstrap
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Node.js package
Network hosts it talks to 3
codeload.github.com· found in install commandjson.schemastore.org· found in codeunpkg.com· found in code
Files it touches
~/.claude/skills/expo-project-bootstrap- Your home directory (~)
What's inside
- Skill name
expo-project-bootstrap- Description
- Creates a new Expo app from empty - SDK 57 stack, Expo Router, root configs, gates, variants, icons - proven by a checker. Use when bootstrapping, setting up or scaffolding an app or repo. Not for adding packages (dependency-management).
- License
- MIT
- Instructions
- 189 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Agent Skills spec issues
- files: referenced but missing: scripts/reset-project.js
Files (111)
- SKILL.md
- app-dependencies.json · assets/
- claude-settings.json · assets/
- shared.json · assets/
- skeleton-package.json · assets/
- template-placeholders.json · assets/
- bootstrap-report.md · examples/
- first-install-and-verify.md · references/
- project-layout.md · references/
- root-files.md · references/
- toolchain-setup.md · references/
- check-lib.mjs · scripts/
- check-skeleton.mjs · scripts/
- bootstrap-plan.mjs · scripts/lib/
- repo-read.mjs · scripts/lib/
- ship-placeholders.mjs · scripts/lib/
- scaffold-app.mjs · scripts/
- selftest.mjs · scripts/
- AGENTS.md · templates/
- CLAUDE.md · templates/
- app.config.ts · templates/
- babel.config.js · templates/
- dependency-policy.json · templates/contracts/
- knip-ignores.json · templates/contracts/
- knip-ignores.schema.json · templates/contracts/
- dot-gitignore · templates/
- dot-npmrc · templates/
- dot-nvmrc · templates/
- dot-prettierignore · templates/
- dot-prettierrc.json · templates/
- eslint.config.mjs · templates/
- jest.config.js · templates/
- jest.setup.ts · templates/
- jest.sim.config.js · templates/
- knip.json · templates/
- lefthook.yml · templates/
- metro.config.js · templates/
- quality-gates.json · templates/
- audit-licenses.ts · templates/scripts/audit/
- license-policy.test.ts · templates/scripts/audit/
- license-policy.ts · templates/scripts/audit/
- system-clock.test.ts · templates/scripts/clock/
- system-clock.ts · templates/scripts/clock/
- banned-packages.test.ts · templates/scripts/deps/
- banned-packages.ts · templates/scripts/deps/
- check-deps.ts · templates/scripts/deps/
- check-npm-config.ts · templates/scripts/deps/
- dependency-policy.test.ts · templates/scripts/deps/
- dependency-policy.ts · templates/scripts/deps/
- effective-npm-config.test.ts · templates/scripts/deps/
- effective-npm-config.ts · templates/scripts/deps/
- engines-floor.test.ts · templates/scripts/deps/
- engines-floor.ts · templates/scripts/deps/
- expo-patch-age.test.ts · templates/scripts/deps/
- expo-patch-age.ts · templates/scripts/deps/
- release-age-excludes.test.ts · templates/scripts/deps/
- release-age-excludes.ts · templates/scripts/deps/
- unpinned-approvals.test.ts · templates/scripts/deps/
- unpinned-approvals.ts · templates/scripts/deps/
- workspace-lockstep.test.ts · templates/scripts/deps/
- …and 51 more
SKILL.md (first lines)
# Expo project bootstrap
Turns an empty (or docs-only) folder into an Expo app with the canonical stack: one app at the repo
root with Expo Router in `src/app/`, every root config, the gate scripts, the dependency policy,
`app.config.ts` with three variants for iOS and Android, a starter route and screen, and placeholder
art. Everything comes from templates that were installed and run end to end; every gate is green on
day one, and a checker proves the skeleton stays that way. The multi-package form is fenced under
"When multi-package" in `references/project-layout.md`.
## Rules that must hold
1. **Generate the skeleton with `scaffold-app.mjs`; never type a config by hand.** Each template was
installed and run (tsc, ESLint, Prettier, Jest, knip, `expo config`); a hand-typed config drifts
from the gates on the first character, and the guardrail then fails for a reason nobody sees.
2. **Bootstrap at the repo root, inside a git repository, and leave pre-existing folders where they
are.** `npm install` installs the git hooks only in a repository, and agents load settings from
the root. Folders that predate the app (docs, design exports) go into `.prettierignore`, ESLint's
`PRE_EXISTING` and the root tsconfig `exclude`, never moved or reformatted. (`format-ignore`,
`lint-ignore`, `tsconfig-program`)
3. **Never overwrite a file that differs from its template without reading both.** The generator
reports a conflict instead of writing; `.gitignore` gains missing lines, `.claude/settings.json`
keeps the developer's keys and allow rules, `CLAUDE.md` gains the `@AGENTS.md` import. Extra deny
or ask rules or hooks are a question for the developer, because the guardrail compares them exactly.
4. **Start from this skeleton, not from `create-expo-app`'s demo.** `app.json`, the demo tabs and
components, `scripts/reset-project.js`, a second routes folder and a second tool config
(`eslint.config.js` from `npx expo lint`, `prettier.config.*`) are leftovers: they ship literal
strings, or a config that Expo merges or that its tool loads before the canonical one. Move what
is needed, delete the rest; never ignore them. (`template-leftover`)
5. **One identity, three variants, both platforms.** The production id is the reverse-DNS id the
developer registers in App Store Connect and Google Play, valid as an iOS bundle id and an Android
package (lower case, dot-separated, each part starting with a letter, no Kotlin or Java keyword);
`development` and `preview` append `.dev` and `.preview`, so all three install side by side.
`app.config.ts` sets `ios.bundleIdentifier`, `android.package` and the adaptive icon from it, and
every icon it names exists. A `com.example` id is allowed only until the first store build. (`app-id`, `platforms`,
`app-files`)
6. **Install exactly the policy's versions, with a committed lockfile.** Specifiers come from
`contracts/dependency-policy.json`: Expo SDK modules keep the `~` that `npx expo install` writes,
everything else is exact at the policy's version, React and React Native included. `overrides` pins all ten
`@typescript-eslint/*` packages at the `typescript-eslint` pin: a second copy crashes every ESLint
run with `Cannot redefine plugin "@typescript-eslint"`. (`pin-exact`, `root-overrides`,
`one-react`, `lockfile`)
7. **Install only what the skeleton uses.** knip fails on an unused dependency, and a package
installed early ages without review; every later package arrives with the skill that first imports
it, through dependency-management. (`banned` keeps the policy's banned and doNotAdd lists out.)
8. **Keep the `.npmrc` policy whole; a dated exclude lives only until its `expires=` date.** npm keeps
the last value of a key, so a later `min-release-age=0` silently switches the policy off; an
exclude outside a dated block, or past its date, is a problem. (`npmrc-policy`, `npmrc-exclude`)
9. **Approve install scripts one package at a time, after reading them.** `strict-allow-scripts` stops
an install on an unreviewed script; an approval is pinned to the reviewed version. Never
`--dangerously-allow-all-scripts`. (`install-scripts`)
10. **Never stub a missing gate script to make `npm run verify` pass.** `i18n:verify` waits for
i18n-strings-and-catalogs; report it as pending. A gate that passes without checking hides every
later failure. (`tooling-files` for the scripts the skeleton does own)
11. **Agents get one contract.** `AGENTS.md` (start green with `npm run -s check:fast`, stop and ask,
never bypass a hook, devices always named) and `CLAUDE.md` = `@AGENTS.md`. An app nested in a
larger repository may take them from there (`"agentInstructions": "parent-repo"`; only up to that
repository's top level counts). (`agents`)
12. **Stop and ask for human steps.** Xcode and its licence, Android SDK licences, `sudo`, store
accounts, signing credentials and trusting the folder in the agent are the developer's; ask once,
name the step and the default that applies meanwhile. Never read or create a signing key.
13. **The first commit stages exactly the generated files, with a `Gate-Change:` trailer, through the
hooks; nothing is pushed unless the developer asks.** Never `git add -A`: the folder may hold the
developer's own uncommitted work.
The checker also guards what the other skills own inside the skeleton, so a bootstrap cannot drift
from them: the canonical scripts (`root-scripts`), Prettier and TypeScript options (`prettier-config`,
`tsconfig-base`), the gate wiring (`knip-config`, `lefthook`, `quality-gates`, `gate-scope`,
`stryker-config`, `claude-settings`), the app config (`app-config`, `metro-cache`, `app-env`) and
unfilled template tokens (`placeholder`). Each rule's reason is in `references/root-files.md`.
## Workflow
1. **Toolchain.** Read [references/toolchain-setup.md](references/toolchain-setup.md) and run its
"Checks before installing" (Node 26.4.0, npm 11.17.0, git; Xcode and the Android SDK only from the
first native build). Ask the developer for any human step that is missing.
2. **Identity.** Ask the developer for the display name and the store id (`com.<org>.<app>`); the slug
and scheme default from the name. Read [references/project-layout.md](references/project-layout.md)
so the tree, the left-out parts and the pre-existing entries are clear. Run `git status`; `git init`
only if the folder is not a repository yet; never discard work you did not make.
3. **Plan without writing:** `node ${CLAUDE_SKILL_DIR}/scripts/scaffold-app.mjs . --app-id com.acme.tasks --name "Tasks"`.
Read the plan: the pre-existing entries it will ignore, the merges, every `conflict` and `leftover`.
4. **Resolve** each conflict with [references/root-files.md](references/root-files.md) ("Merging an
existing repo"): edit the file to the template content, or rerun with `--replace <file>` when it is
only an old draft; ask the developer when a settings rule would be dropped. Delete each leftover
after moving what the app still needs (an `app.json` value goes into `app.config.ts`).
5. **Write:** the same command with `--write`. Rerun the dry run: it must print `0 new, 0 merged` and
`RESULT: PASS`.
6. **Install** exactly as [references/first-install-and-verify.md](references/first-install-and-verify.md)
says ("Install and approve install scripts"): `npm install`, read each pending script, approve one
package at a time until `npm approve-scripts --allow-scripts-pending` lists none; `npm ls react
react-native @typescript-eslint/eslint-plugin` shows one version each.
7. **Gates:** every gate one by one, with no format step first ("The gate runs":
`export:audit` is the only one that bundles through Metro, then `audit:licenses` reads its source
maps) and the Expo config for the three variants on both platforms ("The Expo config for every
variant"). Fix the cause of a failure in the files; a gate is never loosened.
8. **Check:** `node ${CLAUDE_SKILL_DIR}/scripts/check-skeleton.mjs .`; fix every `FAIL` line (each
names the file, the rule and the fix) and rerun until `RESULT: PASS`.
9. **Commit** as "The first commit" says (exact paths, `Gate-Change: initial quality gates`, hooks run).
10. **Report** in the shape of [examples/bootstrap-report.md](examples/bootstrap-report.md): outcome,
at most one request, what to look at, the pending gate in plain words, then the numbers. Hand off
in the order of "What the bootstrap leaves out" (project-layout.md).
## Definition of done
- [ ] `scaffold-app.mjs . --app-id <id> --name <name>` prints `0 new, 0 merged` and `RESULT: PASS`
(no conflict, no leftover); pre-existing folders are untouched and ignored by Prettier, ESLint
and the root tsconfig.
- [ ] `package-lock.json` is committed; `npm approve-scripts --allow-scripts-pending` lists no
package; `npm ls react react-native @typescript-eslint/eslint-plugin` shows one version each.
- [ ] `npm run -s check:fast`, `npm run -s lint`, `npm run -s typecheck`, `npm run -s test:coverage`
(thresholds met), `npm run -s check:unused`, `npm run -s export:audit` (iOS and Android
bundles), `npm run -s audit:licenses`, `node scripts/quality/check-quality-gates.ts` and
`npm run -s check:deps` pass; `npx lefthook validate` prints `All good`.
- [ ] `npx expo config --type public` resolves for `development`, `preview` and `production` (each
with the same `APP_VARIANT` and `EXPO_PUBLIC_APP_VARIANT`), with three ids, names, schemes and
icons on iOS and Android; `APP_VARIANT=production` alone fails.
- [ ] The first commit went through the hooks with a `Gate-Change:` trailer; nothing was pushed
without the developer.
- [ ] The report names the pending gate (`i18n:verify`, i18n-strings-and-catalogs) and the nextFrom zakariaf/ReactNative-Skills, MIT.
More from zakariaf/ReactNative-Skills
- 0.606score
debug-menu-and-test-hooks
zakariaf
Gates test-only code behind one literal TEST_ONLY switch: debug menu, debug link, simulated clock and offline.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
accessibility-as-code
zakariaf
Enforces a11y labels, 44pt targets, 200% text, VoiceOver, TalkBack.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
adaptive-layout
zakariaf
Lays screens out by window, not device: breakpoints, master-detail panes, readable widths, grids.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
admob-ads-and-consent
zakariaf
Builds AdMob ads behind a port - banners, interstitials, rewarded, UMP consent then ATT, pacing, ADS_MODE test IDs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
analytics-and-consent
zakariaf
Gates analytics on opt-in consent: no SDK before a yes, typed events without personal data, ATT.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
android-release-play
zakariaf
Ships Android App Bundles to Google Play: upload key, Play App Signing, AAB gate, versionCode, tracks, rollout.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
architecture-and-boundaries
zakariaf
Places app code in the src/ layout and checks import boundaries: one-way zones, pure core, ports with fakes, one composition root.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
async-safety
zakariaf
Prevents silent async bugs: effect races, stale results, lost promises, leaked listeners and timers, AbortSignal gaps.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
audio-and-haptics-feedback
zakariaf
Builds SFX and haptics behind ports.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
auth-and-secure-storage
zakariaf
Builds sign-in - tokens in expo-secure-store, shared refresh, protected routes, OAuth PKCE, Apple sign-in.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
background-tasks
zakariaf
Builds expo-background-task jobs: idempotent, budgeted runs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
canvas-gestures-and-hit-testing
zakariaf
Turns canvas taps, swipes, drags and aim into typed intents: one gesture module, hit-testing on the drawn layout.
SkillAFreshness: A★ 11Claude Code +9
Signals
- Stars
- 11
- Forks
- 2
- Open issues
- 0
- Last commit (this folder)
- Oct 17, 2026 (11 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/zakariaf/ReactNative-Skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from zakariaf
- 0.606score
admob-ads-and-consent
zakariaf
Builds AdMob ads behind a port - banners, interstitials, rewarded, UMP consent then ATT, pacing, ADS_MODE test IDs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
accessibility-as-code
zakariaf
Enforces a11y labels, 44pt targets, 200% text, VoiceOver, TalkBack.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
canvas-gestures-and-hit-testing
zakariaf
Turns canvas taps, swipes, drags and aim into typed intents: one gesture module, hit-testing on the drawn layout.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
adaptive-layout
zakariaf
Lays screens out by window, not device: breakpoints, master-detail panes, readable widths, grids.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
debug-menu-and-test-hooks
zakariaf
Gates test-only code behind one literal TEST_ONLY switch: debug menu, debug link, simulated clock and offline.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
analytics-and-consent
zakariaf
Gates analytics on opt-in consent: no SDK before a yes, typed events without personal data, ATT.
SkillAFreshness: A★ 11Claude Code +9
Cite this page
expo-project-bootstrap skill. Agent Mart. https://agentmart.dev/skills/zakariaf-expo-project-bootstrap (last updated 2026-10-24)