Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/bitwarden/clients/llms.txt

Use this file to discover all available pages before exploring further.

The browser extension uses webpack for bundling and supports building for multiple browsers and manifest versions.

Prerequisites

Before building, ensure you have:
  • Node.js installed (version specified in root package.json)
  • Dependencies installed: npm install from the repository root

Build Commands

All build commands are defined in apps/browser/package.json.

Development Builds

Build for a specific browser in development mode:
npm run build:chrome

Production Builds

For production-ready builds with optimizations:
npm run build:prod:chrome

Build Configuration

Environment Variables

Builds are configured using environment variables:
  • BROWSER - Target browser (chrome, firefox, safari, edge, opera)
  • MANIFEST_VERSION - Manifest version (2 or 3)
  • NODE_ENV - Build mode (development or production)
  • NODE_OPTIONS - Node.js options (set to --max-old-space-size=8192 for memory)

Example Build Command Breakdown

Here’s what happens when you run npm run build:chrome:
"build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 NODE_OPTIONS=\"--max-old-space-size=8192\" webpack"
1

Set Environment Variables

cross-env sets:
  • BROWSER=chrome - Target Chrome browser
  • MANIFEST_VERSION=3 - Use Manifest V3
  • NODE_OPTIONS="--max-old-space-size=8192" - Allocate 8GB RAM for build
2

Run Webpack

Webpack reads webpack.config.js which calls buildConfig() from webpack.base.js
3

Generate Output

Built extension files are written to build/ directory with browser-specific manifests

Browser Targets

Chrome (Default)

# Development
npm run build:chrome

# Production
npm run build:prod:chrome

# Watch mode
npm run build:watch:chrome
Manifest Version: V3 by default Output: build/ directory with Chrome-compatible extension

Firefox

# Development (Manifest V2)
npm run build:firefox

# Development (Manifest V3)
cross-env MANIFEST_VERSION=3 npm run build:firefox

# Production
npm run build:prod:firefox

# Watch mode
npm run build:watch:firefox
Manifest Version: V2 by default (V3 optional) Special Notes:
  • Uses browser.* namespace instead of chrome.*
  • Supports sidebar action
  • Android support available

Safari

# Development
npm run build:safari

# Production
npm run build:prod:safari

# Watch mode
npm run build:watch:safari
Manifest Version: V2 by default, V3 optional Special Requirements:
  • Requires Xcode and Safari developer tools
  • Native app wrapper needed for distribution
  • Additional packaging step: ./scripts/package-safari.ps1
Safari has unique tab query bugs. Always use BrowserApi.tabsQueryFirstCurrentWindowForSafari() when querying tabs in the current window to avoid getting tabs from other windows.

Edge

# Development
npm run build:edge

# Production
npm run build:prod:edge
Manifest Version: V3 Notes: Uses same build as Chrome with Edge-specific branding

Opera

# Development
npm run build:opera

# Production
npm run build:prod:opera
Manifest Version: V3 Notes: Supports sidebar action like Firefox

Watch Mode for Development

Watch mode automatically rebuilds when source files change:
# Chrome
npm run build:watch:chrome

# Firefox
npm run build:watch:firefox

# Safari
npm run build:watch:safari
The watch mode:
  • Monitors source files for changes
  • Automatically rebuilds on save
  • Preserves build output in build/ directory
  • Does NOT reload the extension in the browser (manual reload required)

Distribution Builds

Create production builds packaged as ZIP files for distribution:
npm run dist:chrome
Distribution commands:
  1. Build production version
  2. Create dist/ directory
  3. Compress to ZIP: scripts/compress.sh dist-{browser}.zip

Distribution Output

ZIP files are created in the dist/ directory:
  • dist-chrome.zip - Chrome Web Store
  • dist-firefox.zip - Firefox Add-ons
  • dist-edge.zip - Microsoft Edge Add-ons
  • dist-opera.zip - Opera Add-ons

Webpack Configuration

The build system uses a modular webpack configuration:
// webpack.config.js
module.exports = buildConfig({
  configName: "OSS",
  popup: {
    entry: path.resolve(__dirname, "src/popup/main.ts"),
    entryModule: "src/popup/app.module#AppModule",
  },
  background: {
    entry: path.resolve(__dirname, "src/platform/background.ts"),
  },
  tsConfig: "tsconfig.json",
});

Entry Points

  • Popup: src/popup/main.ts - Angular application for the extension popup
  • Background: src/platform/background.ts - Service worker entry point
  • Content Scripts: Configured in manifest, built separately

Loading in Browser for Testing

After building, load the extension in your browser:
1

Build the Extension

npm run build:chrome
2

Open Extension Management

  • Chrome: Navigate to chrome://extensions/
  • Firefox: Navigate to about:debugging#/runtime/this-firefox
  • Edge: Navigate to edge://extensions/
3

Enable Developer Mode

Toggle “Developer mode” switch (Chrome/Edge) or click “Load Temporary Add-on” (Firefox)
4

Load Unpacked Extension

  • Click “Load unpacked” (Chrome/Edge)
  • Select the apps/browser/build/ directory
  • For Firefox, select any file in the build/ directory

Common Build Issues

Out of Memory Errors

If builds fail with out-of-memory errors:
# Increase Node.js memory limit
export NODE_OPTIONS="--max-old-space-size=16384"
npm run build:chrome

TypeScript Errors

Clear TypeScript cache:
rm -rf node_modules/.cache
npm run build:chrome

Manifest Version Conflicts

Ensure the correct manifest version for your target browser:
# Chrome/Edge: Manifest V3 only
npm run build:chrome

# Firefox: Specify manifest version explicitly
cross-env MANIFEST_VERSION=3 npm run build:firefox

Next Steps