Skip to main content

Documentation Index

Fetch the complete documentation index at: https://extension.js.org/llms.txt

Use this file to discover all available pages before exploring further.

Write paths the way you naturally author them, and let Extension.js normalize them to runtime-safe output paths. Keep runtime paths working when you move files, rename entries, or change browser targets. Extension.js rewrites supported paths across manifest fields and extension API usage. 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.
  • Path-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

Extension.js normalizes common path inputs 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 Extension.js does not rewrite

To avoid false positives, Extension.js intentionally skips these inputs:
  • http:// and https:// URLs
  • data: URLs
  • chrome:// URLs
  • moz-extension:// URLs
  • Glob patterns (*, ?, {}, [])
  • Non-static/dynamic expressions that the build cannot safely resolve

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 maps to a folder with the same source name. Extension.js bases output paths on the browser-facing extension contract, not on your original authoring path. Extension.js emits all compiled outputs 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 warns you when it cannot resolve a referenced path to a packaged asset (for example, nested src/pages/... or missing public/ files after rewrite).
Extension.js de-duplicates warnings 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.
  • Extension.js preserves absolute OS file paths instead of treating them as extension output paths.
  • Extension.js skips dynamic expressions when it 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; Extension.js may skip dynamic expressions.
  • 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