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:
pnpm create extstart # resolves to the workspace CLI in tooling/createIt 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.
What it does, in order
Section titled “What it does, in order”- 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 ifbillingis kept, and a gate preset ifgateis kept. - The plan: prints every file to delete, marker line to strip, and
npm dependency, manifest permission, and
.env.exampleentry to remove. Nothing changes until you confirm. - Pruning: executes the plan, driven by each module’s
module.jsonmanifest and itsmodule:<id>wiring markers (comments that tag each module’s lines; see the module system guide). - Marker cleanup: strips the remaining
module:*marker comments from kept files; the code inside stays. Opt out with--keep-markers(Rerunning). - Env scaffold: creates
apps/extension/.envfrom the pruned.env.example, prompting per variable; Enter keeps the shown value. An existing.envis left untouched. - Firebase setup (optional, needs the
firebaseCLI): creates or picks a Firebase project and writes its config into every file that carries it. Decline freely; it reruns standalone any time (below). - Backend pointers: prints the Firebase/Stripe setup commands (the
API-driven scripts in
backend/functions) and offers to run the backend doctor. - Verify pass: regenerates WXT types (
wxt prepare) and runspnpm typecheckon the pruned tree;--with-testsadds the unit suites. - Launch checklist: the 4 steps from build to first checkout.
The scope question
Section titled “The scope question”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 thesitewebsite 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 onegit checkoutaway 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.
The optional modules
Section titled “The optional modules”| 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.
Firebase setup (--firebase)
Section titled “Firebase setup (--firebase)”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):
pnpm create extstart --firebaseIt 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.
Headless mode
Section titled “Headless mode”For CI or scripted setups:
pnpm create extstart --yes --scope minimal --name "My Ext"pnpm create extstart --yes --name "My Ext" \ --keep billing,gates,broadcasts --preset value-firstpnpm 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.
Rerunning
Section titled “Rerunning”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.
