vitesse-webext: Vite and Vue 3 Starter Template for WebExtensions
⚡️ WebExtension Vite Starter Template
At a glance
- What is it?
- vitesse-webext is an MIT-licensed Vite-powered TypeScript starter template for building Chrome and Firefox extensions with Vue 3, UnoCSS, instant HMR during development, and automatic component importing. It was originally made for the volta.net browser extension and is a variant of the Vitesse template family.
- Who is it for?
- vitesse-webext is a practical starting point for engineers who want Vue 3, TypeScript, and UnoCSS in a browser extension without wiring up the toolchain from scratch. The pre-configured Vite setup with HMR and the content script injection pattern cover the common cases.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 7 months ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What vitesse-webext Provides for Browser Extension Development
Browser extension development does not fit the standard single-page application toolchain. Extensions have multiple entry points (popup, options page, background script, content script), each with different execution contexts and limitations. Vite's dev server does not map directly to this model; extension manifests require specific asset paths, and content scripts injected into third-party pages need their own build pipeline.
vitesse-webext solves the wiring problem by providing a pre-configured project structure with separate Vite build configurations for the background, the web (popup and options page), and the content script. It includes webextension-polyfill for normalized browser API access across Chrome and Firefox, webext-bridge for messaging between extension contexts, and TypeScript definitions for the manifest. The README states the template is isomorphic across Chrome, Firefox, and other Chromium-based browsers.
Pre-Packed Libraries and What Each One Does
The template bundles a specific set of libraries and Vite plugins. For browser API normalization, it includes `webextension-polyfill`, which wraps browser APIs in promise-based interfaces. For inter-context messaging between the popup, background, and content scripts, it uses `webext-bridge`.
On the build side, three Vite plugins handle development ergonomics. `unplugin-auto-import` lets you use the `browser` API and Vue Composition API functions without explicit import statements. `unplugin-vue-components` auto-imports Vue components from the `src/components` directory. `unplugin-icons` makes icons from any Iconify icon set available as components. UnoCSS handles styling with an on-demand atomic CSS approach.
The coding style is Vue 3 Composition API with `<script setup>` SFC syntax, ESLint configured via `@antfu/eslint-config`, single quotes, and no semicolons. The dev toolchain uses pnpm as the package manager, esno for running TypeScript helper scripts, npm-run-all for parallel script execution, and web-ext for the Firefox auto-reload workflow.
Creating a New Extension and Running the Dev Server
The preferred way to start is through the GitHub template, which creates a new repository from vitesse-webext. Alternatively, clone the template locally with degit for a clean git history:
npx degit antfu/vitesse-webext my-webext
cd my-webext
pnpm iIf pnpm is not installed, install it first with `npm install -g pnpm`. After installing dependencies, start development mode:
pnpm devThis builds the extension into the `extension/` folder and watches for changes. Load the `extension/` folder as an unpacked extension in Chrome's extension settings page. For Firefox, run the dedicated command instead:
pnpm dev-firefoxThe README describes this command as using `web-ext` to auto-reload the extension when files in `extension/` change. Vite handles HMR automatically for most changes, but the README recommends the Extensions Reloader browser extension for cleaner hard reloads when needed.
Gitpod support is included: a `.gitpod.yml` configuration provides a pre-configured cloud development environment accessible from a browser.
Building for Release and Packaging for Extension Stores
To produce a production build:
pnpm buildThis runs a sequence that clears the previous build, then builds the web (popup and options), prepares the manifest, builds the background, and builds the content script. The output goes into the `extension/` directory. From there, the pack scripts produce a `.zip` for stores that accept zip uploads, a `.crx` for Chrome, or an `.xpi` for Firefox:
The `package.json` shows separate `pack:zip`, `pack:crx`, and `pack:xpi` scripts under the `pack` umbrella script. Upload `extension.crx` or `extension.xpi` to the appropriate extension store after packing.
The `src/manifest.ts` file defines the extension manifest with full TypeScript type support, which catches typos in manifest keys at build time rather than at submission time.
Repository Structure and Context Separation
The `src/` directory separates code by extension context. The `contentScript/` subdirectory holds scripts and Vue components injected into web pages. The `background/` subdirectory holds background service worker scripts. The `components/` directory holds Vue components shared between the popup and options page. The `manifest.ts` file at the root of `src/` defines the extension manifest.
The `extension/` directory is the actual extension package root. The `extension/assets/` subdirectory holds static assets for `manifest.json`. The `extension/dist/` directory holds built files and also serves as the stub entry point for Vite during development, since Vite needs a reference to the extension directory.
The three Vite configuration files (`vite.config.mts`, `vite.config.background.mts`, `vite.config.content.mts`) handle the three separate build targets. The `scripts/` directory contains helper TypeScript scripts that prepare files before the build runs.
Template Age and pnpm Dependency Constraints
The template's last push was on 2026-03-03. As of September 2026, that is over six months without an update. The package.json pins pnpm at version 9.7.1 via the `packageManager` field, and the devDependencies include specific versions of tools. Whether those versions remain compatible with the latest browser extension manifest V3 requirements or the current Vite release is not documented in the repository.
The template requires pnpm. None of the development or build scripts are written to work with npm or Yarn directly. Engineers on teams with a standardized npm or Yarn setup will need to either install pnpm or adapt the scripts.
Content scripts injected into third-party pages have access restrictions that vary by browser version and extension manifest version. The template configures content script injection in `src/manifest.ts`, but the README does not document content security policy constraints or the limits on what Vue components can do inside a content script context.
Comparison with WXT and Manually Configured Extension Projects
WXT is another Vite-based framework for browser extension development. Like vitesse-webext, it wraps Vite and provides a project structure with separate entry points for the popup, background, and content scripts. WXT describes itself as providing a framework rather than just a starter template, with its own CLI for project creation and type-safe auto-imports. The practical difference is that vitesse-webext is a copy-and-own template, while WXT is a dependency you install and update via npm.
A manually configured extension project using Vite directly requires writing the separate Vite configs, the manifest TypeScript definitions, and the HMR bridge between Vite and the extension reload mechanism. vitesse-webext provides these out of the box, making it useful for engineers who want to understand how the pieces fit together or who want full control over the toolchain without taking on a framework dependency.
The MIT license places no restrictions on commercial use, and there is no required attribution in the extension itself, only in the source repository.
Editorial conclusion
vitesse-webext is a practical starting point for engineers who want Vue 3, TypeScript, and UnoCSS in a browser extension without wiring up the toolchain from scratch. The pre-configured Vite setup with HMR and the content script injection pattern cover the common cases. The template's last push was on 2026-03-03, which is over six months before September 2026; engineers who need ongoing compatibility updates with the latest browser extension APIs or tool versions should check whether the template's dependencies are still current before building on it.
Frequently asked questions
Does vitesse-webext support Firefox as well as Chrome?
Yes. The README describes it as isomorphic for Chrome, Firefox, and other Chromium-based browsers. A separate `pnpm dev-firefox` command uses web-ext to auto-reload the extension in Firefox during development.
Why does vitesse-webext use pnpm instead of npm?
The template is configured with pnpm as the required package manager, as set in the `packageManager` field of `package.json`. The README instructs users to install pnpm with `npm install -g pnpm` if it is not already available. The build and development scripts are not configured for npm or Yarn.
How does vitesse-webext handle communication between the popup and the content script?
The template pre-packs `webext-bridge`, a library for messaging between extension contexts such as the background, popup, and content script. The README lists it under the WebExtension Libraries section without documenting the API, but the library's own documentation covers message sending and receiving.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/antfu-collective-vitesse-webext)