Skip to content

Quickstart ​

The Quickstart takes a new extension from a template to a build you can hand to someone else. Follow it the first time you connect a project. Every later project repeats steps 3 to 6.

Quick start ​

bash
npx extension@latest create my-extension --template=init
cd my-extension
npm install
npm run dev

The first command scaffolds the extension and commits it. The last one opens a browser with the extension loaded and reloads it on every file change.

How it works ​

1. Create an extension ​

The scaffold above is the Extension.js framework. The other way in is to import a repository you already have.

extension.dev/new shows six starting surfaces. Each tile opens extension.dev/import?template=<slug> directly, and Browse templates opens templates.extension.dev, a separate app where the full catalog runs live in the page. Its Import to extension.dev button sends you to the same extension.dev/import?template=<slug> address, which is where step 3 continues. The catalog covers popups, sidebars, content scripts, and framework combinations. For a full-page surface instead of a popup, start from the New Tab template. See Templates.

2. Run it locally ​

bash
npm run dev

The dev server launches a browser with the extension loaded and reloads it on every file change. It binds to 127.0.0.1:8080, and --port moves it.

On a machine with no browser, such as a container or a CI runner, add --no-browser. The dev server still starts, builds, and watches. It opens nothing.

bash
npm run dev -- --no-browser --port 9000

This step is the Extension.js framework, documented at extension.js.org. Nothing has touched the platform yet.

3. Connect the project ​

Step 1 left a repository with one commit, on the branch git init gives a new repository. What is missing is the remote, because the platform builds from a repository GitHub can serve.

bash
gh repo create my-extension --private --source=. --push

Any way of creating the remote works, and gh is the shortest. There is no git add and no git commit step here. Both answer "nothing to commit, working tree clean" on a fresh scaffold. A repository that reaches the import with no commits at all is the one case with nothing to build, and the import says so instead of starting a build. See Import.

Open extension.dev/new and sign in with GitHub. Signed in, that address forwards you to the console's /new, the repository picker. Choosing a repository there sends you to extension.dev/import with it selected. The import analyzes the tree, finds the manifest, detects the browsers the extension declares, and infers a build command and output directory per browser.

/import needs a GitHub App installation before it can write anything, and it asks for one in the middle of the flow. The selector lists the installations you already have and offers Authorize new installation. That sends you to github.com/apps/extensiondev/installations/new, asks which account and repositories the App may touch, and returns you to the same import page with the installation selected. The button that does the work reads Create repository and deploy for a template and Create project for a repository.

Sign-in is gated during the alpha. An account that is not on the invite list lands on /subscribe with an explanation instead of reaching the console.

See Import for what the analysis reads, Projects for what a project owns, and Workspaces for who can see it.

4. Build for every browser ​

Push a commit. The project builds one artifact per configured browser from that commit, in a build repository the platform owns, and lists the build under Builds in the console. Build minutes never burn on your account.

A build that starts from a push runs without you, so it is metered on its own. Free carries 25 of them a month. Past that the push is refused, and Rebuild on the latest build under Builds runs the same commit by hand. See extension.dev/pricing.

Each build records the commit it came from, the browsers it produced, and the integrity hash of every artifact, so a build can be checked later without trusting the console that served it.

5. Share the build ​

A build does not need a release to be looked at. Share it from the build in the console, or from an agent with the MCP server configured by calling extension_preview_web with share: true. Either way the link renders the exact bytes of that build in a browser emulator.

The platform hands out two share links, and they run on two clocks. The uploaded preview is a ?preview= address that lives for your plan's window and can be revoked. The other comes from extension_publish in the agent, which uploads nothing and answers with your project's own build page, carrying a ?share= token when the project is private. The table under Reference has both. See Share an unpublished build for review and Publish a build.

6. Promote and publish ​

A new project answers to two release channels, preview and stable. Any other channel is one you create. Promotion checks the build's environment stamp against the target channel's binding. See Environments and Promote gates.

When a build sits in stable, submit it to the stores from the project's Submissions tab in the console, from an agent with extension_submit, or with POST /api/cli/stores/submit and a project token. Store credentials are entered once in project settings and reused by every submission. See Channels and Publishing.

Reference ​

Share linkMinted byAddressLifetime
Uploaded previewShare in the console, or extension_preview_web with share: true?preview=30 days on Free, 365 days on Pro; revocable
Build linkextension_publish from an agent?share= on a private project7 days by default. Ask for more with ttlHours, within the plan's share window: 30 days on Free, 365 days on Pro
Channel linkA public channel, or any channel of a public project/channels/<channel>, no tokenNever expires
AllowanceFreePro
Builds started by a push, per month25350
Projects per workspace110

When it fails ​

  • npm run dev errors before the platform is involved. That is the framework. Debug it with the docs at extension.js.org.
  • The project exists but shows no builds. Builds start on push. Push a commit, then watch Builds in the console.
  • Pushes built earlier this month and stopped. Free carries 25 builds from a push a month, and you have used them. Click Rebuild on the latest build under Builds to run the same commit now. The count resets at the start of the next month.
  • A share link stopped opening because it expired. An uploaded preview link lasts 30 days on Free and 365 days on Pro. Share the same build again and the expired address is reused with a fresh window, so the link you already sent starts working again. A ?share= token from extension_publish lasts 7 days unless the agent passed ttlHours, and you get a new one by asking the agent to publish again.
  • A share link stopped opening because it was revoked. A revoked address is dead for good. Re-sharing the same build mints a different address. Send the new link; the old one never comes back.
  • Promotion to stable is refused. The build's environment stamp does not match the channel's binding. Build for the target channel, then promote. See Promote gates.

Next ​