What browser extensions can do
The exact API surface varies by browser, but most extensions do one or more of:- Change page content. Inject CSS or scripts into specific URLs (content scripts).
- Add browser UI. Render a popup from the toolbar action, a side panel, an options page, or a custom new-tab page.
- React to browser events. Listen for tab updates, navigation, downloads, alarms, or messages from the page.
- Store data. Read and write to extension-scoped storage that survives across sessions.
- Call privileged APIs. Manage cookies, declarative network requests, bookmarks, history, downloads, or notifications, gated by
permissions.
Browser extension files
Every browser extension is a folder of static assets and code, signed and packaged for distribution:| File or folder | Purpose |
|---|---|
manifest.json | Declares the extensionโs name, version, permissions, entry points, and metadata. |
| Background script | Long-lived event handler. Manifest V3 uses a service worker on Chromium. |
| Content scripts | Code injected into matching web pages. |
| HTML pages | Popup, options, side panel, or new-tab UI. |
| Icons and assets | Toolbar icons, locale strings, and other static resources. |
.ts, .tsx, .jsx, .vue, .svelte, CSS, Less, Sass) down to this on-disk layout and produces a separate folder per browser target.
JavaScript, TypeScript, HTML, and CSS in extensions
Browser extensions are built with the same languages as the web. JavaScript and TypeScript drive logic. HTML defines extension pages. CSS (or Less, Sass, CSS modules, Tailwind) styles them. Extension.js wires all of this through Rspack with extension-aware defaults so you do not have to configure bundlers per browser. See JavaScript and TypeScript files in browser extensions for which file extensions land where.Chrome extensions vs Firefox extensions
Chrome and Firefox extensions share the WebExtensions API, but a few differences matter every time you build:- Background: Chrome (Manifest V3) requires
background.service_worker. Firefox usesbackground.scriptswith non-persistent event pages. - Runtime API: Firefox exposes
browser.*natively. Chromium useschrome.*. Use--polyfillto bridge the gap on Chromium. - Permissions: Browsers evaluate a few
permissionsandhost_permissionsentries differently. - Distribution: Chrome ships through the Chrome Web Store, Firefox through addons.mozilla.org, Edge through the Edge Add-ons store.
How Extension.js helps
Without a framework, building a browser extension means hand-writingmanifest.json, configuring a bundler per browser, wiring reload-on-save by hand, polyfilling APIs, and producing separate Chrome, Firefox, and Edge artifacts. Extension.js does this for you:
- One project, one
manifest.json, separatedist/<browser>outputs. - TypeScript, React, Vue, Svelte, Preact, and modern CSS work without configuration.
extension devreloads the extension, content scripts, and HTML pages on save.extension buildproduces signed-ready artifacts per browser target.
Next steps
- Try
extension createto scaffold an extension in seconds. - Learn about Manifest V3 and the API differences between browsers.
- See Cross-browser compatibility for the build pipeline.
- Choose a browser target for development.

