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 per target browser.

Manifest capabilities

CapabilityWhat it gives you
Browser-specific field filteringKeep one manifest file while emitting target-specific output
Path normalizationResolve runtime-safe output paths automatically
Reference validationFail early when HTML/script/CSS/JSON/icon files are missing
Targeted outputsGenerate manifest artifacts per browser target in dist/<browser>

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 guard ensures a copied static asset does not overwrite the generated manifest.

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:
Manifest fieldFile type expected
action.default_popup.html
background.page.html
background.service_worker.js, .jsx, .ts, .tsx, .mjs
browser_action.default_popup.html
chrome_url_overrides.bookmarks.html
chrome_url_overrides.history.html
chrome_url_overrides.newtab.html
content_scripts.js.js, .jsx, .ts, .tsx, .mjs
content_scripts.css.css, .scss, .sass, .less
declarative_net_request.rule_resources.json
devtools_page.html
icons.png, .jpg, …Other image formats
options_ui.page.html
options_page.html
page_action.default_popup.html
sandbox.pages.html
side_panel.default_path.html
sidebar_action.default_panel.html
storage.managed_schema.json
theme_icons.png, .jpg, …Other image formats
user_scripts.api_script.js, .jsx, .ts, .tsx, .mjs
web_accessible_resources.png, .jpg, .css, .js

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 the browser-facing contract. 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

Manifest change typeTypical outcome
Update non-structural values (for example, descriptions/permissions metadata)Hard reload flow
Update asset path values that still resolve cleanlyRecompile + hard reload flow
Add/remove script or page entrypoints in manifestRestart required
Introduce invalid/missing referenced filesBuild error (fix first, then rerun)

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