manifest.json and compiles them into dedicated background outputs. It applies browser-specific reload behavior during development.
Template examples
action

ai-chatgpt

Background capabilities
Background script support
Declare background scripts with thesemanifest.json fields:
background.type can also affect runtime mode (module vs classic service worker behavior).
Sample background script declaration
Example background script declaration inmanifest.json:
Development behavior
- Extension.js tracks service worker/source changes 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).
- Extension.js treats structural entrypoint changes more strictly than regular module edits.
Firefox: service worker translated to an event page
Firefox does not run MV3background.service_worker (loading such an add-on fails with “background.service_worker is currently disabled. Add background.scripts.”). You don’t need to special-case it: for the Firefox build, Extension.js automatically translates a background.service_worker entry into a background.scripts event page pointing at the same compiled bundle. Author one background.service_worker and it loads on both Chromium and Firefox.
Chromium: scripts translated to a service worker
The translation runs in the other direction too. In a Chromium MV3 build, abackground.scripts array becomes background.service_worker pointing at the compiled bundle.
Chromium MV3 rejects the whole extension whenever background.scripts is present, even next to a valid service_worker. Extension.js therefore always removes the scripts key from the emitted Chromium MV3 manifest. When the source declares both fields, the existing service_worker entry wins.
MV3 service worker lifecycle
background.service_worker runs under the browser’s service-worker lifecycle, not as a long-running process.
That means:
- In-memory state can disappear between events.
- Design long-running work around events, not process permanence.
- Startup should stay small and predictable.
- Your code should restore important state from storage or recompute it safely.
background.scripts only for MV2-style compatibility cases. For MV3-first extensions, treat the service worker as the central coordinator for browser API calls and cross-context communication.
Output behavior
Common outputs include:background/service_worker.jsbackground/scripts.js
Module and classic notes
background.type: "module"uses module worker semantics.- Classic service worker mode uses
importScripts-based chunk loading behavior. - Avoid dynamic imports in background code that must load immediately on startup.
Runtime-loaded files
Some files never appear as import statements but still must ship with the extension. Extension.js traces these into the output so the built extension behaves like the source loaded unpacked in the browser:importScripts(...)dependencies of classic service workers. String-literal arguments are resolved recursively (a dependency can callimportScriptsitself) against the emitted worker location, so worker-relative URLs keep working even though the worker moves tobackground/service_worker.js. WebAssembly sibling files loaded by wasm-bindgen glue (*_bg.wasm) ship alongside their loader.chrome.scripting.executeScript({files: [...]})andinsertCSS({files: [...]})payloads. Files referenced only fromfiles:arrays (not declared in manifestcontent_scripts) are copied verbatim at their extension-root paths.
Recommended architecture
- Keep the background entry thin and move feature logic into shared modules.
- Use the background context as the central coordinator for messaging, storage access, and browser API calls.
- Restore durable state from storage instead of assuming the background script stays running permanently.
- 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 background-level browser API access.
Best practices
- Prefer
background.service_workerfor 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
- Understand update outcomes in dev update behavior.
- Persist durable runtime state with Storage.
- Coordinate contexts with Messaging.
- Learn more about JavaScript in development.
- Continue with content scripts.
- Troubleshoot service worker behavior in Manifest V3 troubleshooting.

