JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 22
  • Score
    100M100P100Q67348F
  • License MIT

Lightning-fast browser extension build system with first-class HMR, interactive scaffolding, and cross-browser support (Chrome, Firefox, Safari, Edge — Manifest V3).

Package Exports

  • extforge
  • extforge/csui
  • extforge/env
  • extforge/logger
  • extforge/messaging
  • extforge/plugins
  • extforge/storage
  • extforge/storage/react
  • extforge/testing
  • extforge/testing/vitest

Readme

ExtForge

The build system for Manifest V3 browser extensions.

CI npm version npm downloads License: MIT Node Docs


ExtForge is a zero-config build system for Manifest V3 browser extensions. One config, every browser. esbuild-powered dev server with true 0-reload UI updates via React Fast Refresh. First-party packages for storage, messaging, and Shadow-DOM-mounted content UIs.

Quick start

pnpm dlx extforge init my-extension
cd my-extension
pnpm install
pnpm dev

Open chrome://extensions, enable Developer mode, and Load unpacked from dist/chrome/.

Full quick-start guide →

What it does

Build & dev

  • Cross-browser by default. One config emits a manifest tailored to each browser. Browser-specific quirks handled automatically.
  • True 0-reload UI updates. SWC-powered React Fast Refresh for popup/options/sidepanel — components update with state preserved. Falls back gracefully (full reload) when @swc/core isn't installed.
  • Versioned HMR protocol (v3). Targeted module swaps for UI-only changes; full reload for manifest / background / content-script changes. CSS hot swap, infinite reconnect.
  • Cross-browser API compat checking. MDN BCD-driven — catches chrome.tabGroups.update() on Safari at build time, with per-line opt-out.
  • Production-ready packaging. extforge package produces store-ready .zip archives.

First-party runtime packages

  • extforge/storage + extforge/storage/react — typed chrome.storage wrapper with watch API and useStorage() hook. localStorage fallback for non-extension contexts.
  • extforge/messaging — typed RPC over chrome.runtime. defineHandler / sendMessage with full inference via the augmentable MessageMap interface. Plus typed Ports API.
  • extforge/csui — Content Script UI. Drop a file at src/contents/*.csui.tsx, export default defineCSUI({matches: [...]}, render), and ExtForge auto-discovers it, registers it in the manifest, and mounts it inside a Shadow DOM at runtime.
  • extforge/env.env loading with Vite-style precedence. EXTFORGE_PUBLIC_* keys are inlined into bundles via esbuild's define.
  • extforge/testingchrome.* fakes for runtime/storage/tabs/action/scripting plus a vitest preset.
  • extforge/logger — structured logger used by the CLI. Exposes scoped loggers, timers, and a JSON transport for piping CI output into log aggregators.

Extensibility

  • Typed plugin API. Hooks for config, manifest, build, and dev-reload events. Legacy plugin shape still works.
  • extforge doctor — 9 preflight checks for node version, config validity, icons, HMR port, browser overrides, permissions, and cross-browser API support.

Install

pnpm add -D extforge

Requires Node 20+. Optional: pnpm add -D @swc/core react-refresh to enable React Fast Refresh in dev. See install guide for npm/yarn/bun.

Docs

Full documentation lives at extforge.arshadshah.com:

Examples

Working reference extensions live in examples/:

  • vanilla-popup — popup + content + background in plain TypeScript. Uses extforge/messaging and extforge/storage.
  • react-csui — React popup + Shadow-DOM-mounted React widget injected via extforge/csui (auto-discovered).
  • env-config.env loading via extforge/env: EXTFORGE_PUBLIC_* inlining and the public/private key split.

Both build for chrome and firefox from a single config, exercised end-to-end in tests-e2e/ via Playwright with Chrome's new headless mode.

Contributing

Issues and PRs welcome. Run pnpm install && pnpm test to verify your environment. User-visible changes need a changeset:

pnpm changeset

See .changeset/README.md for the workflow.

License

MIT — see LICENSE.