Repo tour
ExtensionStart is a pnpm + Turborepo monorepo. Here’s the map, top to bottom.
apps/extension – the extension app
Section titled “apps/extension – the extension app”WXT + React 19 + Tailwind 4 + Firebase. WXT generates manifest.json
from wxt.config.ts per browser; never hand-edit a manifest.
entrypoints/background/: one module per concern, imported byindex.tsin a fixed order:migrations→errors→logs→firebase(auth) →billing→gates→broadcasts→update-notice. All event listeners are registered at the top level (why that matters).- Surfaces:
popupandsidepanelmount the same account/settings tabs (no separate options page);welcomeis the first-run tour;contentholds the shadow-DOM UI: status bar, gate walls, highlighter demo;offscreenis the auth fallback. Demo surfacesnewtabanddevtoolsbuild only withWXT_DEMO_SURFACES=true. utils/: the typed messaging protocol, settings store, shadow-UI mount, DOM observer, highlight persistence, error reporting, page bridge.hooks/:useAuth,useBilling,useTheme.site.config.ts: every user-facing name, email, URL, and pricing-copy string. Rebranding starts (and mostly ends) here.
packages/ – framework-free cores
Section titled “packages/ – framework-free cores”Each package is a framework-free core with a thin React subpath (/react)
where UI bindings exist. Lint enforces importing only public entrypoints.
| package | what it is |
|---|---|
core-ext |
defineStore / defineStorageView / defineMessaging / defineProxyService / defineAlarm / defineMigrations (the MV3 survival kit) plus a /testing chrome mock |
core-auth |
auth strategies (web-auth-flow default, offscreen fallback), anonymous-first linking, typed auth errors |
core-billing |
entitlement snapshot + states matrix, billing API client, storage-backed hooks (useEntitlement('paid')) |
gate |
trigger primitives and combinators, the gate evaluator (cooldowns/escalation/chaining), presets, and the GateWall UI (/react) |
ui |
Button/Card/Input/Badge/Skeleton/Dialog/Toast (CVA variants over Base UI) |
backend/functions – one Hono app
Section titled “backend/functions – one Hono app”A single Hono app on Cloud Functions v2, deliberately self-contained:
Firebase packs it standalone, so it can’t import workspace TypeScript.
Routes: /gateConfig, /billing/checkout, /billing/portal,
/billing/webhook, /gate/events, /auth/revoke, /errors. The billing
core is port-based (StripeGateway / EntitlementStore / ClaimsWriter) so
alternative payment providers can implement the same contract.
tooling/
Section titled “tooling/”create/: thecreate-extstartwizard (reference).config/: shared ESLint/Prettier/tsconfig presets and themodule.schema.jsonthat validates module manifests.
module.json everywhere
Section titled “module.json everywhere”Every prunable feature module carries a module.json manifest declaring
its files, dependencies, env vars, and manifest permissions. The wizard’s
pruner consumes these: dropping a module removes its code, deps, env
entries, and permissions together. Details in the
module system guide.
Commands you’ll use
Section titled “Commands you’ll use”From the repo root:
pnpm build # build everythingpnpm typecheck # TypeScript, strict, workspace-widepnpm lint # ESLint, workspace-widepnpm turbo run test # unit testsExtension-specific root aliases (the long form
pnpm --filter @extensionstart/extension <script> always works too):
pnpm dev # dev build + watchpnpm e2e # Playwright against the built extensionpnpm zip # store-ready zip (also zip:firefox, zip:edge)pnpm audit:remote-code # scan built outputBackend (from backend/functions/): pnpm serve (emulators),
pnpm firebase:deploy, pnpm seed:stripe, pnpm stripe:webhook,
pnpm doctor, pnpm test, pnpm test:rules, pnpm test:lifecycle.
