Skip to main content
Browser extensions use JavaScript, TypeScript, HTML, CSS, and a manifest.json to define behavior, UI, permissions, and browser integration. This page covers the file extensions you will see in a browser extension project and which ones land where. If you are looking for “extension” as in a software add-on for Chrome or Firefox, start at What is a browser extension? instead.

JavaScript file extensions: .js and .mjs

Browser extensions accept the same JavaScript file extensions the rest of the web platform uses: In Manifest V3, the background service_worker runs as a module when manifest.json includes "type": "module" in the background block. See Manifest V3 troubleshooting for the details.

TypeScript file extensions: .ts and .tsx

TypeScript works as a first-class source language in Extension.js: You do not need to write a tsconfig.json from scratch. Extension.js ships sensible defaults. Types for chrome.*, browser.*, import.meta.env, and the public env keys come from @types/chrome and Extension.js’s own ambient types. See TypeScript.

React file extensions: .jsx and .tsx

React in a browser extension uses the standard JSX file extensions: React works inside extension pages (popup, options, side panel, new-tab) and inside content scripts injected into web pages. See React for setup and shadow-DOM patterns.

Browser extension files: manifest.json, background, content scripts, pages

Beyond JavaScript and TypeScript source, a browser extension folder usually contains: Extension.js compiles your .ts, .tsx, .jsx, .vue, .svelte, .css, .less, .scss, and .module.* source down to that on-disk layout. It produces a separate folder per browser target (dist/chrome, dist/firefox, dist/edge).

How Extension.js compiles JavaScript and TypeScript extensions

When you run extension dev or extension build, Extension.js:
  1. Reads manifest.json and finds every entry point (background, content scripts, popup, options, side panel, new-tab, web-accessible HTML).
  2. Resolves source files referenced from those entries, including imports across .ts, .tsx, .jsx, .vue, .svelte, and stylesheet types.
  3. Compiles through Rspack with extension-aware defaults: code splitting where it helps, no chunking where the browser refuses it (service workers, content scripts).
  4. Emits the result into dist/<browser> with a manifest filtered for that target.
You write source in any of the file extensions above. Extension.js handles the bundling, polyfills, reload-on-save loop, and per-browser packaging.

Next steps