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:
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://andhttps://URLsdata:URLschrome://URLsmoz-extension://URLs- Glob patterns (
*,?,{},[]) - Non-static/dynamic expressions that cannot be safely resolved at build time
Manifest output examples
Assuming target browser chrome:
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:
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/andscripts/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/, andpublic/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
devas they usually indicate path mismatches before packaging.
Next steps
- Learn more about Special Folders.
- Learn more about Web Accessible Resources.
