tsc. This page covers the packages that step needs to resolve chrome.* and browser.*.
What Extension.js generates
When a project uses TypeScript,extension dev and extension build write an extension-env.d.ts file beside package.json. It is regenerated on every run, so do not edit it.
The file pulls in the ambient types that the extension package publishes:
extension-env.d.ts
The
EXTENSION_* environment keys are typed here too. That is why process.env.EXTENSION_MODE resolves without extra setup.
Install @types/chrome for the chrome namespace
extension/types declares the browser global itself, but it reaches the chrome namespace through a reference:
@types/chrome is installed in your project. Extension.js does not install it, and the templates do not declare it.
A scaffolded TypeScript project that calls chrome.storage therefore fails tsc:
When you write browser.* instead
Thebrowser global is typed by extension/types, which maps it onto webextension-polyfill. For the full namespace shape, add the matching types package:
Keep extension-env.d.ts in the include list
The generated file only helps when TypeScript reads it. The scaffoldedtsconfig.json names it:
tsconfig.json
tsconfig.json for a project that has none, that file carries no include array. TypeScript then reads every file under the project folder, so it finds extension-env.d.ts anyway. An include array of your own that omits the file breaks asset imports and the browser global.
Symptoms and fixes
Best practices
- Treat
extension-env.d.tsas build output. Commit it if you like, but never edit it. - Add
@types/chrometo any TypeScript project that callschrome.*, including one that you scaffolded from a template. - Run
tsc --noEmitin continuous integration. The Extension.js build does not fail on type errors.
Next steps
- Read the rest of the TypeScript setup.
- Learn about environment variables that the types declare.
- Review cross-browser compatibility.

