Templates
A template is a working extension you start from instead of an empty directory. Reach for one when you want something that builds, runs, and loads in a browser before you change a line.
The six starters
Each starter is the same small extension, a sidebar panel plus a content script, in a different language or framework. Pick the one you write in.
| Starter | Written in | Create it |
|---|---|---|
| JavaScript | Plain JavaScript | --template javascript |
| TypeScript | TypeScript | --template typescript |
| React | React with TypeScript | --template react |
| Preact | Preact with TypeScript | --template preact |
| Vue | Vue with TypeScript | --template vue |
| Svelte | Svelte with TypeScript | --template svelte |
Every starter page shows the same three ways in, with a clip of each:
- The terminal.
npx extension@latest create my-extension --template <slug>, thennpm run dev. No account and nothing hosted. This is the Extension.js framework on your machine. - An agent. With the MCP server installed, "Create a React extension and run it" calls
extension_createwith the template andextension_devto run it. - The catalog. templates.extension.dev runs each template live in the page and turns it into a private repository of your own with one click.
Quick start
npx extension@latest create my-extension --template react
cd my-extension
npm run devThe first command creates the project and installs its dependencies. The last one opens a browser with the extension loaded.
How it works
templates.extension.dev renders the whole catalog, one card per template. Each template page carries a copyable CLI command, a download of the built extension, and one click that turns the template into a repository of your own. The preview on that page is the template compiled and running, not a screenshot of it.
The repository click opens www.extension.dev/import?template=<slug>&private=true, carrying the repository name and description from the card. That page creates a private GitHub repository from the template and connects it as a project. Configuration works signed out. Creating the repository writes to your GitHub account, so that step needs a GitHub session. See Import for what happens on that page.
The catalog does not author its templates. It pins a commit of extension-js/examples and ships it as a content-addressed artifact. A fidelity harness re-derives the catalog from the pinned source and fails when the rendered listing and the real files disagree.
Reference
What a catalog page shows:
| Route | Shows |
|---|---|
/<slug> | The template running live in the browser emulator |
/<slug>/instructions | What the template does and how to work in it |
/<slug>/source | The real files, browsable in the page |
/a/<artifactId> | A shared artifact, kept for 90 days |
What the 59 templates cover:
| Group | Examples |
|---|---|
| Surfaces | Popup, side panel, new tab, devtools |
| Content scripts | Main world, multiple entries, CSS modules, Sass, Less |
| Frameworks | React, Preact, Svelte, Vue, TypeScript, plain JavaScript |
| Tooling | ESLint, Prettier, Stylelint, Playwright, Nx and Turborepo monorepos |
| AI | ChatGPT, Claude, Gemini, Perplexity, Transformers.js |
For a full-page surface instead of a popup, start from the New Tab template.
When it fails
- Repository creation is refused with a rate limit. The limit is 20 repository creations per hour per user, and the
429answer carries the seconds to wait. Wait, or run the CLI command on the template page in the meantime. - A fix made to a template does not last. The next corpus sync overwrites it. Fix the template in extension-js/examples, and the next pin brings the fix into the catalog.
- An
/a/<artifactId>link returns nothing. Shared artifacts are kept 90 days. Republish from the source that produced the artifact. - The create click asks for a sign-in. Browsing and configuration work signed out. Creating the repository writes to your GitHub account, so that step needs a GitHub session.
Next
- Import for what the template hands off to
- Quickstart for the walk from a template to a shared build
extension_createfor every input the agent can set