Background scripts

Run extension-wide logic in background contexts with clear support for both MV2-style background scripts and MV3 service workers.

Extension.js reads background entries from manifest.json, compiles them into dedicated background outputs, and applies browser-specific reload behavior during development.

Background capabilities

CapabilityWhat it gives you
MV2/MV3 compatibilitySupport background.scripts and background.service_worker entries
Dedicated background outputsEmit background runtime files per active manifest shape
Reload-aware developmentApply hard reload/restart behavior for structural changes
Worker mode controlRespect background.type module/classic runtime behavior

Background script support

The following fields in manifest.json are used to declare background scripts:

Manifest fieldFile type expectedDev behavior
background.service_worker.js, .ts, .mjs, .tsxhard reload flow
background.scripts.js, .ts, .mjs, .tsxHMR-compatible path

background.type can also affect runtime mode (module vs classic service worker behavior).

Sample background script declaration

Below is an example of how to declare a background script within the manifest.json file:

{
  "manifest_version": 3,
  "name": "My Extension",
  "version": "1.0.0",
  "background": {
    "service_worker": "./scripts/background.ts"
  }
}

Development behavior

  • Service worker/source changes are tracked and can trigger hard extension reload.
  • Manifest changes affecting background entries can trigger restart-required diagnostics.
  • Browser launch plugins apply target-specific hard reload strategies (Chromium/Firefox).
  • Structural entrypoint changes are treated more strictly than regular module edits.

MV3 service worker lifecycle

background.service_worker runs under the browser's service-worker lifecycle, not as a permanently alive process.

That means:

  • in-memory state can disappear between events
  • long-running work should be designed around events, not process permanence
  • startup should stay small and predictable
  • important state should be rehydrated from storage or recomputed safely

Use background.scripts only for MV2-style compatibility cases. For MV3-first extensions, treat the service worker as the source of truth for privileged orchestration.

Output behavior

Common outputs include:

  • background/service_worker.js
  • background/scripts.js

Exact output depends on which manifest field is active after browser filtering.

Module and classic notes

  • background.type: "module" uses module worker semantics.
  • Classic service worker mode uses import-scripts chunk loading behavior.
  • Keep dynamic import usage conservative in background runtime-critical paths.
  • Keep the background entry thin and move feature logic into shared modules.
  • Use the background context as the privileged coordinator for messaging, storage access, and browser API orchestration.
  • Rehydrate durable state from storage instead of assuming a singleton process.
  • Use alarms, explicit event listeners, and small feature modules instead of one large startup path.

Common mistakes

  • Treating the service worker like a permanently running server process.
  • Keeping critical state only in memory.
  • Doing expensive startup work on every event wakeup.
  • Putting too much feature logic in popup or content-script code when it actually needs privileged coordination.

Best practices

  • Prefer background.service_worker for MV3-first extensions.
  • Keep background entry files small and delegate logic to shared modules.
  • Avoid expensive startup work in service workers; initialize lazily where safe.
  • Treat manifest background field edits as structural changes in dev flow.
  • Route privileged actions through validated message handlers.
  • Store durable settings and caches in browser storage, not only in module-level variables.

Next steps