.">
🛣️

Predictable path resolution

Write paths the way you naturally author them, and let Extension.js normalize them to runtime-safe output paths.

Keep runtime paths working when files move, entries are renamed, or browser targets change. Extension.js rewrites supported paths consistently across manifest fields and extension API usage so compiled assets resolve correctly inside dist/<browser>.

How it works

Path resolution runs in two places:

  • Manifest compilation pipeline: resolves manifest-declared paths to emitted assets.
  • Resolve plugin for JS/TS: rewrites static path literals passed to supported extension APIs (for example runtime.getURL, tabs.update, scripting.*, action.*, sidePanel.*).

Supported input styles

Common path inputs are normalized as follows:

Input styleExampleNormalized output
Public root (absolute)/public/icons/icon.pngicons/icon.png
Public root (relative)public/icons/icon.png, ./public/icons/icon.pngicons/icon.png
Root absolute/foo/bar.jsfoo/bar.js
Root special folder/pages/popup.njkpages/popup.html
Special folderspages/popup.html, scripts/content.tsxpages/popup.html, scripts/content.js
Parent-relative from author file../scripts/content.tsscripts/content.js (when resolving to project root special folder)

Extension mapping for pages/ and scripts/ includes:

  • .ts, .tsx, .js, .jsx -> .js
  • .njk, .nunjucks, .html -> .html
  • .scss, .sass, .less, .css -> .css

Cases intentionally not rewritten

To avoid false positives, these inputs are intentionally skipped:

  • http:// and https:// URLs
  • data: URLs
  • chrome:// URLs
  • moz-extension:// URLs
  • Glob patterns (*, ?, {}, [])
  • Non-static/dynamic expressions that cannot be safely resolved at build time

Manifest output examples

Assuming target browser chrome:

Manifest fieldInput PathOutput Path
action.default_popup/src/popup.htmlaction/index.html
background.page/src/background.htmlbackground/index.html
background.service_worker/src/background.tsbackground/service_worker.js
browser_action.default_popup/src/popup.htmlaction/index.html
chrome_url_overrides.newtab/src/newtab.htmlnewtab/index.html
content_scripts.js/src/content_script.tscontent_scripts/content-0.js
content_scripts.css/src/content_style.csscontent_scripts/content-0.css
devtools_page/src/devtools.htmldevtools/index.html
options_ui.page/src/options.htmloptions/index.html
sandbox.pages/src/sandbox.htmlsandbox/page-0.html
side_panel.default_path/src/sidepanel.htmlsidebar/index.html
sidebar_action.default_panel/src/sidebar_panel.htmlsidebar/index.html
storage.managed_schema/src/storage_schema.jsonstorage/managed_schema.json
user_scripts.api_script/src/user_script.tsuser_scripts/api_script.js

Not every manifest field rewrites to a folder with the same source name. The emitted path is based on the browser-facing extension contract, not on the original authoring path.

All compiled outputs are emitted under dist/<browser>.

Referencing output files

For browser APIs like chrome.runtime.getURL(), prefer stable, output-root paths:

const iconUrl = chrome.runtime.getURL('/icons/icon.png')
console.log(iconUrl)

Output: chrome-extension:<extension-id>/icons/icon.png

Diagnostics and safety checks

The resolver emits warnings when a referenced path cannot be resolved to a packaged asset (for example, nested src/pages/... or missing public/ files after rewrite).
Warnings are de-duplicated per file transform pass to reduce noise.

Important path rules

  • Leading / means extension output root, not filesystem root.
  • public/... and /public/... normalize to output-root assets.
  • pages/ and scripts/ are special folders with extension mapping rules.
  • Absolute OS file paths are preserved instead of being treated like extension output paths.
  • Dynamic expressions are skipped when Extension.js cannot safely determine the final packaged path.

Best practices

  • Keep pages/, scripts/, and public/ at project root for predictable rewrites.
  • Use static literals for extension API paths when possible; dynamic expressions may be skipped.
  • Treat /public/... as output-root assets and avoid source-relative assumptions at runtime.
  • Validate warnings during dev as they usually indicate path mismatches before packaging.

Next steps