Skip to main content
Extension.js runs TypeScript across every extension context: background, content scripts, popup, options, and sidebar. It uses the Rspack + SWC pipeline by default. You do not need a separate tsc step, a ts-loader, or an extra bundler rule. Builds do not need the typescript package at all. SWC compiles your sources and strips the types. The package matters only for editor tooling and a tsc --noEmit typecheck. For that reason a missing typescript package never fails a build, unlike missing framework integration packages.

When TypeScript is a good fit

  • You want safer refactors and clearer contracts across extension contexts.
  • You share logic between background scripts, content scripts, and UI surfaces.
  • You need predictable API usage when working with AI-generated code.

Template examples

new-typescript

new-typescript template screenshot Best for building a new-tab extension with TypeScript defaults already configured.
Repository: extension-js/examples/new-typescript

content-typescript

content-typescript template screenshot Best for injecting TypeScript-powered content scripts into existing pages.
Repository: extension-js/examples/content-typescript

Generated ambient types

For TypeScript projects, Extension.js generates an extension-env.d.ts file at your project root with ambient declarations (browser/runtime globals, EXTENSION_PUBLIC_* env, and bundler types). Both dev and build regenerate it, so editor types and a CI tsc --noEmit stay in sync. Commit it (or git-ignore it). Either works; it’s recreated on the next run.

Usage with an existing extension

Add TypeScript to an existing extension with the steps below.

Installation

  1. Install TypeScript as a development dependency:
  1. Initialize the TypeScript configuration file tsconfig.json:

Configuration

TypeScript detection and requirements

Extension.js looks for tsconfig.json next to your package.json.
  • .ts source files with no tsconfig.json is a hard error. Create the file next to package.json to fix it.
  • A project that declares the typescript dependency but has no tsconfig.json and no .ts sources yet gets a baseline one written for it.
Example baseline configuration:
Two defaults worth knowing:
  • moduleResolution is bundler, which models the Rspack + SWC pipeline. The removed node (node10) mode fails tsc --noEmit on TypeScript 7.
  • jsx is react-jsx only when Extension.js detects a JSX framework in the project. Without one, it stays preserve.

Automatic types

Extension.js generates extension-env.d.ts in your project root during development. This file includes type declarations for Extension.js APIs and browser polyfill types.

Transpilation vs type-checking

The default bundler pipeline compiles TypeScript but does not run full tsc type-checking as part of bundling. Recommended scripts:

Next steps

Video walkthrough