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
| Capability | What it gives you |
|---|---|
| Browser-specific field filtering | Keep one manifest file while emitting target-specific output |
| Path normalization | Resolve runtime-safe output paths automatically |
| Reference validation | Fail early when HTML/script/CSS/JSON/icon files are missing |
| Targeted outputs | Generate manifest artifacts per browser target in dist/<browser> |
Where Extension.js reads the manifest
src/manifest.json(preferred when present)manifest.jsonat project root
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:- emits the manifest asset from your source file
- filters browser-prefixed keys for the active browser target
- applies manifest overrides/path normalization for extension outputs
- 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:*
chromium:keybackground.firefox:scriptsbackground.chromium:service_worker
Supported manifest fields
Common entrypoint-related fields include:| Manifest field | File 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
permissionssmall and intentional - keep
host_permissionsas narrow as the feature allows - move non-core capabilities into
optional_permissionsoroptional_host_permissionswhere possible - review permission scope whenever content-script matches or background capabilities change
Output behavior
Extension.js rewrites manifest paths to predictable output locations when needed. Two important examples:background.service_workerbecomesbackground/service_worker.jsside_panel.default_pathbecomessidebar/index.html
content_scripts/content-0.jscontent_scripts/content-0.css
Development behavior
- When
manifest.jsonchanges, 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 type | Typical outcome |
|---|---|
| Update non-structural values (for example, descriptions/permissions metadata) | Hard reload flow |
| Update asset path values that still resolve cleanly | Recompile + hard reload flow |
| Add/remove script or page entrypoints in manifest | Restart required |
| Introduce invalid/missing referenced files | Build 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.jsonunderpublic/.
Next steps
- Understand update outcomes in dev update behavior.
- Design least-privilege access in Permissions and host permissions.
- Learn how Extension.js handles browser-specific fields.
- Understand dev update flow in page reload and hot module replacement (HMR).

