Skip to content
Agentmart
Submit a tool

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

IndexedMIT★ 11
Write a review

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.

We use your email only for this newsletter. Privacy

About

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).

No 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 command
  • json.schemastore.org · found in code
  • unpkg.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 next

From zakariaf/ReactNative-Skills, MIT.

More from zakariaf/ReactNative-Skills

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
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from zakariaf

Cite this page

expo-project-bootstrap skill. Agent Mart. https://agentmart.dev/skills/zakariaf-expo-project-bootstrap (last updated 2026-10-24)