Skip to content

Setup wizard

create-extstart configures your clone in place. It never downloads templates and never touches files outside the repo. Run it from anywhere inside the clone:

Terminal window
pnpm create extstart # resolves to the workspace CLI in tooling/create

It has zero runtime dependencies and refuses to run on a dirty git tree, so every change it makes is one git diff away from review and one git checkout away from undo.

  1. Questionnaire: extension name and description (written to apps/extension/site.config.ts, which the manifest reads), the scope question below, target browsers, a monetization model if billing is kept, and a gate preset if gate is kept.
  2. The plan: prints every file to delete, marker line to strip, and npm dependency, manifest permission, and .env.example entry to remove. Nothing changes until you confirm.
  3. Pruning: executes the plan, driven by each module’s module.json manifest and its module:<id> wiring markers (comments that tag each module’s lines; see the module system guide).
  4. Marker cleanup: strips the remaining module:* marker comments from kept files; the code inside stays. Opt out with --keep-markers (Rerunning).
  5. Env scaffold: creates apps/extension/.env from the pruned .env.example, prompting per variable; Enter keeps the shown value. An existing .env is left untouched.
  6. Firebase setup (optional, needs the firebase CLI): creates or picks a Firebase project and writes its config into every file that carries it. Decline freely; it reruns standalone any time (below).
  7. Backend pointers: prints the Firebase/Stripe setup commands (the API-driven scripts in backend/functions) and offers to run the backend doctor.
  8. Verify pass: regenerates WXT types (wxt prepare) and runs pnpm typecheck on the pruned tree; --with-tests adds the unit suites.
  9. Launch checklist: the 4 steps from build to first checkout.

Before any per-module prompt, the wizard asks one question: start minimal or keep everything?

  • minimal: what a monetized popup extension needs and nothing else: billing, gate, and the site website template (your Chrome Web Store listing needs a privacy-policy page). The side panel, broadcasts, error reporting, and all demo surfaces are dropped; each is one git checkout away later.
  • everything: keep every optional module (the same as --yes). Prune later by re-running the wizard (see --keep-markers).
  • choose: the per-module walkthrough, in dependency order.

Headless, this is --scope minimal / --scope everything; an explicit --keep list overrides --scope.

id what you get drop it when
billing Stripe checkout/portal, webhook-written entitlements, pricing UI, useEntitlement your extension is free
gate sign-in walls and paywalls with timing presets (requires billing) you have no walls to show
sidepanel the account/settings UI docked in Chrome’s side panel (sidePanel permission, opened from the toolbar icon) your product is popup-only
site your extension’s public website (Astro): landing page, CWS-ready privacy policy, terms, changelog you already have a website
broadcasts remote banner announcements + the post-update changelog notice you never need to reach installs between releases
error-reporting consent-gated crash reports to your own backend (opt-in; the wizard defaults this one to No) you don’t want crash telemetry
content-demo the highlighter demo feature (the shadow-UI mount itself always stays) always, once you’ve read its source; it’s a teaching demo
demo-newtab branded new-tab override demo (requires billing; built only with WXT_DEMO_SURFACES=true) you don’t ship a new-tab surface
demo-devtools devtools panel streaming the support log (built only with WXT_DEMO_SURFACES=true) you don’t need it

Core modules (auth, the extension core, UI primitives) aren’t removable. Dependencies resolve automatically: keeping gate force-keeps billing; dropping billing drops gate (and demo-newtab) too.

One deliberate exception: the pruner leaves backend/** in place even for dropped modules. The backend is one self-contained Cloud Function and unused routes are harmless.

The Firebase step also runs standalone. It skips the questionnaire and prune, needs no clean git tree, and is safe to re-run (it asks before overwriting a real config):

Terminal window
pnpm create extstart --firebase

It creates or picks a project via the firebase CLI, writes the SDK config into every file that carries it, and prints a deep-linked checklist of the manual console steps (sign-in providers, Blaze plan, OAuth client). The full walkthrough lives in the Sign-in guide; headless flags are in the CLI reference.

For CI or scripted setups:

Terminal window
pnpm create extstart --yes --scope minimal --name "My Ext"
pnpm create extstart --yes --name "My Ext" \
--keep billing,gates,broadcasts --preset value-first
pnpm create extstart --dry-run --scope minimal # print the plan only

--yes accepts flags/defaults with no prompts; without --scope/--keep it keeps everything, and --keep wins when both are given. --dry-run prints the plan and changes nothing. Full flag list: CLI reference.

The wizard is built for one configuration pass on a fresh clone. Because it requires a clean git tree, you can experiment safely: run it, inspect git diff, and git reset --hard to try a different module combination.

By default the marker-cleanup step means a second pass can rebrand but no longer prune; run the first pass with --keep-markers to keep that option open (semantics). Adding a module back after committing means restoring its files from git history, so keep what you’re unsure about.