> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Create command to scaffold extension projects

> Scaffold a new browser extension project from an official template with one CLI command. Choose React, Vue, Svelte, TypeScript, or vanilla JS.

`create` scaffolds files, configuration, and starter scripts for the selected template and optionally installs dependencies.

For a file-by-file tour of the generated tree, see [What create generates](/docs/getting-started/create-your-first-extension#what-create-generates).

## When to use `create`

* Start a new extension from scratch.
* Spin up multiple proof-of-concept ideas quickly.
* Standardize onboarding for your teammates with consistent template defaults.

## Create command capabilities

| Capability | What it gives you |
| - | - |
| Template scaffolding | Start with official templates and a ready project structure |
| Dependency install | Optionally install required packages after scaffold |
| Path flexibility | Create by project name or explicit folder path |
| Fast onboarding | Move from empty folder to runnable extension quickly |

## Usage

<Note>
  **Using Yarn?** The `yarn dlx` command requires Yarn 2 or later. Yarn 1 does
  not include `dlx` and fails with a "Command not found" error. On Yarn 1, use
  the `npm` tab (`npx`) instead.
</Note>

<CodeGroup>
  ```bash npm theme={null}
  npx extension@latest create <extension-name|extension-path> [options]
  ```

  ```bash pnpm theme={null}
  pnpx extension@latest create <extension-name|extension-path> [options]
  ```

  ```bash yarn 2+ theme={null}
  yarn dlx extension@latest create <extension-name|extension-path> [options]
  ```

  ```bash bun theme={null}
  bunx extension@latest create <extension-name|extension-path> [options]
  ```

  ```bash deno theme={null}
  deno run -A npm:extension@latest create <extension-name|extension-path> [options]
  ```
</CodeGroup>

## Arguments and flags

| Flag | Alias | What it does | Default |
| - | - | - | - |
| `[path or name]` | - | Project folder/name to create. | required |
| `--template <name\|url>` | `-t` | Catalog name, GitHub URL, or ZIP URL to scaffold from. | `typescript` |
| `--install [boolean]` | - | Installs dependencies after scaffolding. | `false` |
| `--source <source>` | - | Attribution tag for where this create started (for example `cli`). Recorded in anonymous telemetry only. | unset |
| `--output <pretty\|json>` | - | Result format. `json` prints a schema-1 envelope on stdout. | `pretty` |

When you want the default TypeScript starter, omit `--template` entirely. Add `--template=<slug>` only for another stack from the [official examples](https://github.com/extension-js/examples/tree/main/examples). `--template` also accepts a GitHub URL or a ZIP URL, so you can scaffold from any repository.

From 4.1.19, a template URL must use `https://`. `create` refuses a plain `http://` URL, and a download that redirects to `http://`, before it writes the project. To allow `http://` on a network that you trust, set `EXTENSION_ALLOW_HTTP_TEMPLATE=true`.

The catalog holds 53 templates in 6 groups: starters, sidebar, content scripts, new tab, toolbar action, and special folders. Run `extension create --help` for the full list. The default `typescript` template downloads the catalog archive like every other name. Only the `javascript` template ships inside the CLI. When you omit `--template`, `EXTENSION_CREATE_TEMPLATE_URL` is not set, and the download fails, `create` falls back to that bundled `javascript` template and says so, naming the network error, so an offline machine still gets a project. An explicit `--template` that fails to download fails loudly instead.

A scaffold has one package manager. A starter's `packageManager` pin (or a `pnpm-workspace.yaml` it ships) decides it, otherwise the manager that invoked `create` does. The `packageManager` field written to `package.json`, the `--install` run, and the printed next steps all name that same manager.

## Template corpus pinning

Catalog downloads are pinned to one immutable commit of the examples repository. Two scaffolds of the same version therefore produce the same bytes. Two environment variables override the pin:

* `EXTENSION_CREATE_TEMPLATE_REF` points at another ref. Set it to `main` to restore floating behavior.
* `EXTENSION_CREATE_TEMPLATE_URL` points at another archive URL entirely. When it is set and that archive cannot be used, `create` fails and never falls back to the bundled template.

Each scaffold writes a `.extension-create.json` provenance file into the project. It records the create version, the template, and the source, plus the resolved ref when the template came from the catalog archive, so template drift stays auditable. The bundled `javascript` starter records `"source": "bundled"` and no ref.

## Machine output with `--output json`

`--output json` prints one schema-1 envelope on stdout and routes scaffold progress lines to stderr:

* A successful run prints a `status: "created"` frame. Its `value` carries `projectPath`, `projectName`, `template`, and `depsInstalled`.
* Failures print `ok: false` with an `error.code`: `E_TEMPLATE_NOT_FOUND` for an unknown catalog name, `E_NETWORK` for a failed download (a refused connection, an HTTP error, or a timeout), `E_DESTINATION_NOT_EMPTY` or `E_DESTINATION_NOT_WRITABLE` for destination problems.
* A template URL that answers with something other than a ZIP archive, or with a damaged one, fails with `E_REMOTE_ZIP_INVALID` and leaves nothing on disk.
* An archive with an entry outside its folder fails with `E_REMOTE_ZIP_INVALID` too, from a template URL or from `EXTENSION_CREATE_TEMPLATE_URL`. `create` checks every entry before it writes one, so the message says the archive was refused, names the entry, and gives no advice to try again.
* `EXTENSION_CREATE_TIMEOUT_MS` bounds the whole template fetch, retry included. A fetch that runs out of time fails with `E_NETWORK` and the reason `No answer within N seconds`.
* An `EXTENSION_CREATE_TEMPLATE_URL` that fails never falls back to the bundled `javascript` template. A page or a damaged archive fails with `E_REMOTE_ZIP_INVALID`, and a refused connection, an HTTP error, or a timeout fails with `E_NETWORK`. The message names the variable, and nothing is left on disk.
* A plain `http://` template URL without `EXTENSION_ALLOW_HTTP_TEMPLATE=true` fails with `E_INVALID_OPTION`.

## Shared global options

Also supports [Global flags](/docs/workflows/global-flags).

## Example commands

<CodeGroup>
  ```bash npm theme={null}
  npx extension@latest create my-extension --template=newtab-react
  ```

  ```bash pnpm theme={null}
  pnpx extension@latest create my-extension --template=newtab-react
  ```

  ```bash yarn 2+ theme={null}
  yarn dlx extension@latest create my-extension --template=newtab-react
  ```

  ```bash bun theme={null}
  bunx extension@latest create my-extension --template=newtab-react
  ```

  ```bash deno theme={null}
  deno run -A npm:extension@latest create my-extension --template=newtab-react
  ```
</CodeGroup>

<Frame>
  <iframe className="w-full aspect-video rounded-xl" src="https://www.youtube-nocookie.com/embed/9Bm-PAQdQks?rel=0" title="Extension.js: npx extension create scaffolds a project" loading="lazy" allow="encrypted-media; picture-in-picture; fullscreen" allowFullScreen />
</Frame>

<CodeGroup>
  ```bash npm theme={null}
  npx extension@latest create my-extension --install
  ```

  ```bash pnpm theme={null}
  pnpx extension@latest create my-extension --install
  ```

  ```bash yarn 2+ theme={null}
  yarn dlx extension@latest create my-extension --install
  ```

  ```bash bun theme={null}
  bunx extension@latest create my-extension --install
  ```

  ```bash deno theme={null}
  deno run -A npm:extension@latest create my-extension --install
  ```
</CodeGroup>

## Available templates

<Tip>
  For the full, continuously updated list of templates, browse the [examples
  repository](https://github.com/extension-js/examples/tree/main/examples).
</Tip>

<CardGroup cols={2}>
  <Card title="JavaScript" icon="js" href="https://github.com/extension-js/examples/tree/main/examples/javascript">
    Minimal bundled starter. Use when you want a clean baseline or are offline.
  </Card>

  <Card title="TypeScript (default)" icon="typescript" href="https://github.com/extension-js/examples/tree/main/examples/typescript">
    Typed sidebar starter with `tsconfig.json` preconfigured.
  </Card>

  <Card title="React" icon="react" href="https://github.com/extension-js/examples/tree/main/examples/newtab-react">
    React UI wired for content scripts and popup views.
  </Card>

  <Card title="Vue" icon="vuejs" href="https://github.com/extension-js/examples/tree/main/examples/newtab-vue">
    Vue UI with single-file component (SFC) support baked in.
  </Card>
</CardGroup>

## Best practices

* Start from a template that matches your UI/runtime needs to reduce setup drift.
* Keep the first run small, then add extra tooling after verifying baseline command flow.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.