Extension.js Documentation

repository·main·Indexed 26 days ago

https://github.com/extension-js/extension.js

A cross-browser extension framework for building extensions for Chrome, Edge, Firefox, and Safari. It features a zero-config development experience with Hot Module Replacement (HMR), automated Manifest V3 support, and a suite of Rspack plugins including CompatibilityPlugin for cross-browser normalization, JsFrameworksPlugin for React, Vue, Svelte, and TypeScript support, and the extension-create engine for project scaffolding.

Tokens
53.4K
Snippets
88
Records
338
Agent score
88%

What's inside Extension.js

  1. Overview of the `plugin-reload` development pipeline

    main

    When running in development mode, ReloadPlugin applies the following steps in order to prepare the extension for HMR and debugging:

    1. StripContentScriptDevServerRuntime: Removes the rspack-dev-server startup runtime from emitted content scripts so the browser can own the reinjection.
    2. SetupReloadStrategy: Configures dev-only background entry setup and runtime behavior.
    3. InjectScriptsReplayShim: Injects the shim required for script replaying.
    4. InjectBridgeProducer: Instruments the control-bridge to forward background-SW and content-script console output to the dev-server.
    5. InjectBridgeRelay: Completes the control-bridge instrumentation for unified logging.
  2. Understand the `feature-scripts` pipeline in `plugin-web-extension`

    main

    feature-scripts is the scripts pipeline for plugin-web-extension. It manages the transformation of manifest script declarations into Rspack entries and ensures content scripts are correctly wrapped for isolated execution.

    Key responsibilities include:

    • Converting manifest script declarations into Rspack entries.
    • Wrapping content scripts to allow mounting into isolated roots.
    • Maintaining separate runtime behavior for content scripts versus page/script entries.
    • Enforcing the canonical content-script contract required by plugin-reload and plugin-browsers.

    Note: Dev-only reload/HMR strategies are handled by plugin-reload, which decorates the entries created by this pipeline.

  3. Understand Extension.js release channels

    main

    Extension.js uses three distinct release channels via npm distribution tags. Choose the appropriate channel based on your stability requirements:

    • Stable: Uses the latest npm dist-tag. These are clean semver releases.
    • Next: A manual pre-release channel using the next npm dist-tag. These must use pre-release semver (e.g., 3.0.0-next.1).
    • Canary: A manual, silent channel using the canary npm dist-tag. These are used for rapid testing and do not trigger GitHub Releases, changelogs, or Discord notifications. They can use auto-generated versions if left empty during the workflow trigger.
  4. Understand project detection and root semantics

    main

    Extension.js uses specific rules to identify your project root and resolve paths:

    Project Detection

    • Paths/URLs: Commands accept local paths or remote URLs. GitHub URLs are downloaded via go-git-it. Other HTTP(S) URLs are treated as zip archives.
    • Monorepos: The nearest manifest.json is resolved recursively. The nearest valid package.json is then located and used as the project root (the webpack context).

    Root Semantics

    • Project Root: The directory containing the nearest valid package.json.
    • Fallback: If no package.json is found, the manifest directory is used as the fallback project root (Web-only mode).
    • Path Resolution: Special folders and root-relative paths are anchored at the package root. For example, public/, pages/, scripts/, and URLs starting with / resolve relative to the package root (e.g., /logo.png $\rightarrow$ <packageRoot>/public/logo.png).
  5. Quickstart with Extension.js

    main

    To create a new browser extension project from scratch, use the extension@latest create command. Once created, navigate to the directory and start the development server to enable Hot Module Replacement (HMR) for background, content, popup, and options scripts.

    Supported package managers: npm, pnpm, yarn, bun, and deno.

    npx extension@latest create my-extension
    cd my-extension
    npm run dev
  6. Run a GitHub sample directly

    main

    Extension.js allows you to run any GitHub repository containing a Chrome extension sample directly in your browser without manual setup. Pass the URL of the specific sample directory to the dev command.

    npx extension@latest dev https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/functional-samples/sample.page-redder --browser=edge
  7. Enable debug output

    main

    To see detailed maintainer-level internals, enable debug mode. This adds greppable lines to the output without changing existing user-facing lines. You can enable it using the --debug flag on any command or by setting the EXTENSION_DEBUG environment variable to 1.

    Note: The older --author, --author-mode, and EXTENSION_AUTHOR_MODE flags are deprecated aliases for --debug.

  8. Use the StaticAssetsPlugin for asset management

    main

    The StaticAssetsPlugin automatically manages common static assets (images, fonts, and miscellaneous files) by emitting them to a stable assets/ directory. It provides smart defaults, handles SVG inlining for small files, and applies content hashing in production for efficient caching.

    Supported Asset Types

    • Images: png, jpg, jpeg, gif, webp, avif, ico, bmp
    • Fonts: woff, woff2, eot, ttf, otf
    • Misc Files: txt, md, csv, tsv, xml, pdf, docx, doc, xls, xlsx, ppt, pptx, zip, gz, gzip, tgz
    • SVGs: Small SVGs (≤2KB) are inlined; larger ones are emitted to assets/.

    Hashing Behavior

    • Production: Uses assets/[name].[contenthash:8][ext] for long-term caching.
    • Development: Uses assets/[name][ext] for easier debugging.
    import {StaticAssetsPlugin} from './plugin-static-assets'
    
    export default {
      plugins: [
        new StaticAssetsPlugin({
          manifestPath: '/abs/path/to/manifest.json',
          mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
        })
      ]
    }
  9. Publish a release via GitHub Actions

    main

    Releases are managed through the Release – Publish workflow located at .github/workflows/publish-release.yml. This workflow is triggered manually via workflow_dispatch.

    Workflow Inputs

    • channel: Select from next, stable, or canary.
    • version: An explicit semver string.
      • For stable: Use clean semver (e.g., 3.0.0).
      • For next: Use pre-release semver (e.g., 3.0.0-next.17).
      • For canary: You may leave this empty to auto-generate a version in the format <base>-canary.<run_number>.<short_sha>.

    Release Behavior by Channel

    FeatureStableNextCanary
    npm dist-taglatestnextcanary
    GitHub ReleaseYesYesNo
    GitHub DeploymentYesYesNo
    Discord NotificationYesYesNo
    Changelog/NotesYesYesNo