Skip to main content
Keep extension builds predictable by treating manifest.json as the source of truth for entrypoints, assets, and browser-specific behavior. Extension.js compiles your manifest and filters browser-prefixed fields. It rewrites runtime paths, validates referenced files, and produces a ready-to-load manifest for each target browser.

Manifest capabilities

Where Extension.js reads the manifest

  • src/manifest.json (preferred when present)
  • manifest.json at project root
Extension.js does not use public/manifest.json as the source manifest. When a project has a package.json, Extension.js ignores public/manifest.json. This prevents a copied static asset from overwriting the manifest that Extension.js generates.

What Extension.js does with it

During dev/build, the manifest pipeline:
  1. Emits the manifest asset from your source file.
  2. Filters browser-prefixed keys for the active browser target.
  3. Applies manifest overrides/path normalization for extension outputs.
  4. Validates referenced files (HTML/scripts/CSS/icons/JSON) and fails early when missing.

One manifest, multiple browsers

Browser-prefixed keys let you keep one manifest file while still targeting browser-specific behavior:
  • chromium:*, chrome:*, edge:*
  • firefox:*, gecko:*
These prefixes can apply to top-level keys and nested manifest fields. Examples:
  • chromium:key
  • background.firefox:scripts
  • background.chromium:service_worker

Supported manifest fields

Common entrypoint-related fields include:

Permissions design

The manifest is also where your extension declares what it can do. Extension.js compiles the manifest, but you still need good permission design.
  • Keep permissions small and intentional.
  • Keep host_permissions as narrow as the feature allows.
  • Move non-core capabilities into optional_permissions or optional_host_permissions where possible.
  • Review permission scope whenever content-script matches or background capabilities change.
For permission strategy, see Permissions and host permissions.

Output behavior

Extension.js rewrites manifest paths to predictable output locations when needed. Two important examples:
  • background.service_worker becomes background/service_worker.js
  • side_panel.default_path becomes sidebar/index.html
Extension.js also normalizes content scripts by manifest entry index:
  • content_scripts/content-0.js
  • content_scripts/content-0.css
Those emitted paths are what the browser actually loads. Use source paths in authoring, then let Extension.js rewrite them for output.

Development behavior

  • When manifest.json changes, Extension.js recompiles and triggers extension hard reload flow.
  • If manifest entrypoint structure changes (for example, script list changes), Extension.js may require a dev server restart.
  • Missing files referenced by manifest fields fail compilation with manifest-focused errors.

Change outcome matrix

What Extension.js repairs for you

Some manifest shapes make Chromium refuse to load the extension outright, with little explanation. Extension.js diagnoses these before the browser launches and auto-repairs the fatal ones. Each repair prints a warning that names the field and the reason. See Manifest refusals for the catalogue of refusal causes and repairs.

Legacy path warnings

In development builds only, the compiler warns when the emitted manifest still contains one of these deprecated generated paths:
  • devtools_page/devtools_page.html
  • options_ui/page.html
  • background/page.html
  • browser_action/default_popup.html
  • page_action/default_popup.html
  • side_panel/default_path.html
  • sidebar_action/default_panel.html
Each match produces a ManifestLegacyWarning. Extension.js rewrites these paths to the standardized folders in the next major version.

Best practices

  • Keep manifest paths relative to the extension source/output model and use leading / only when you mean extension output root.
  • Use browser-prefixed keys instead of maintaining separate manifest files per browser.
  • Keep entrypoint changes deliberate; adding/removing manifest scripts often changes reload semantics in dev.
  • Validate icons, JSON resources, and content-script assets as part of continuous integration (CI) to catch path regressions early.
  • Do not place manifest.json under public/.

Next steps