wxt-dev / wxt-dev/wxt

Feature: Support loading additional extensions alongside main extension

Open
#1,997 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

upstream
Dominant language
TypeScript
Stars
10.5k
Forks
564
PR merge metrics
No merged PRs in 30d

Description

Feature Request: Support loading additional extensions via additionalExtensions config

Repository: https://github.com/wxt-dev/wxt

Summary

Add support for loading additional extensions alongside the WXT extension during development via a new additionalExtensions config option in webExt.

Use Case

When developing browser extensions with WXT, developers often need to load multiple extensions simultaneously:

  1. WebAuthn Testing: Extensions using WebAuthn require a virtual authenticator extension for automated testing
  2. Debugging Tools: Loading React DevTools or Redux DevTools alongside the main extension
  3. Integration Testing: Testing interactions between multiple extensions
  4. Development Helpers: Loading helper extensions that provide test fixtures or mock APIs

Currently, developers must manually load additional extensions through chrome://extensions after WXT opens the browser, which:

  • Breaks the development workflow
  • Doesn't persist across browser restarts in dev mode
  • Can't be automated in CI/Tilt environments

Proposed API

Add an additionalExtensions config option to the webExt configuration:

// wxt.config.ts
export default defineConfig({
  webExt: {
    startUrls: ['http://localhost:3000'],
    // New option: array of paths to additional extension directories
    additionalExtensions: [
      '/path/to/webauthn-extension',
      '/path/to/devtools-extension',
    ],
  },
})
TypeScript Types
interface WebExtConfig {
  // ... existing options

  /**
   * Additional extension directories to load alongside the main extension.
   * Useful for loading helper extensions like WebAuthn authenticators or debugging tools.
   * Only supported for Chromium browsers.
   */
  additionalExtensions?: string[];
}

Proposed Implementation

Pass the additionalExtensions array to web-ext-run as additionalSourceDirs:

// dist/core/runners/web-ext.mjs
const finalConfig = {
  ...userConfig,
  target: wxt.config.browser === "firefox" ? "firefox-desktop" : "chromium",
  sourceDir: wxt.config.outDir,
  // Pass additional extensions to web-ext-run
  additionalSourceDirs: wxtUserConfig?.additionalExtensions ?? [],
  noReloadManagerExtension: true,
  noReload: true,
  noInput: true,
};
Diff
--- a/dist/core/runners/web-ext.mjs
+++ b/dist/core/runners/web-ext.mjs
@@ -50,6 +50,8 @@ export function createWebExtRunner() {
         target: wxt.config.browser === "firefox" ? "firefox-desktop" : "chromium",
         sourceDir: wxt.config.outDir,
         // Don't add a "Reload Manager" extension alongside dev extension, WXT
+        // Support loading additional extensions (requires web-ext-run support)
+        additionalSourceDirs: wxtUserConfig?.additionalExtensions ?? [],
         // already handles reloads intenrally.
         noReloadManagerExtension: true,
         // WXT handles reloads, so disable auto-reload behaviors in web-ext

Example Usage

// wxt.config.ts
const webAuthnExtensionPath = process.env.WEBAUTHN_EXTENSION_PATH;

export default defineConfig({
  modules: ['@wxt-dev/module-react'],

  webExt: {
    startUrls: ['http://localhost:5174'],
    ...(webAuthnExtensionPath ? {
      additionalExtensions: [webAuthnExtensionPath],
      // Optionally use persistent profile for auth state
      chromiumProfile: process.env.CHROME_PROFILE_DIR,
      keepProfileChanges: !!process.env.CHROME_PROFILE_DIR,
    } : {}),
  },
})

Dependencies

This feature requires web-ext-run to support loading multiple extensions. A corresponding feature request should be filed there for additionalSourceDirs support.

Upstream issue: (link to web-ext-run issue when created)

Notes

  • Additional extensions are loaded via CDP Extensions.loadUnpacked (Chrome 126+) or --load-extension flag (older versions)
  • Only the main WXT extension receives HMR/reload capabilities
  • Additional extensions are loaded once at browser startup
  • Only supported for Chromium browsers (Chrome, Edge, etc.)

Alternatives Considered

  1. Using chromiumArgs with --load-extension: Doesn't work with Chrome 126+ which uses CDP instead of the flag
  2. Post-launch CDP injection: Would require connecting to Chrome's debugging port separately, adding complexity

Real-World Use Case

We're building a Canton Network wallet extension that uses WebAuthn for authentication. During development and E2E testing with Playwright, we need to load a virtual WebAuthn authenticator extension alongside our main extension. This feature would enable:

# Tiltfile
if enable_webauthn:
    extension_env["WEBAUTHN_EXTENSION_PATH"] = webauthn_extension_path

Without this feature, we have to use complex workarounds involving CDP injection scripts that are fragile and don't integrate well with WXT's development workflow.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the webExt configuration types and dist/core/runners/web-ext.mjs, then verify the current web-ext-run support for additionalSourceDirs and the required upstream feature. Done means the new additionalExtensions option is typed, passed to the runner for Chromium development sessions, and its documented limitations are handled without changing reload behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.