Chrome Extension Development Setup: The 2026 Starter Guide | ExtensionBooster
Let's talk about something that matters if you're working with Chrome extensions right now.
The Key Points
- Chrome Extension Development Setup: The 2026 Starter Guide | ExtensionBooster Most “build your first Chrome extension” tutorials skip the part that actually slows people down: the setup
- Json and a popup, and 20 minutes later you are fighting a stale service worker, a polluted browser profile, and an editor that has never heard of chrome
- This guide is the part everyone skips
The Details
Chrome Extension Development Setup: The 2026 Starter Guide | ExtensionBooster Most “build your first Chrome extension” tutorials skip the part that actually slows people down: the setup. They jump straight to manifest. json and a popup, and 20 minutes later you are fighting a stale service worker, a polluted browser profile, and an editor that has never heard of chrome. This guide is the part everyone skips. It walks through the development environment you set up once and reuse for every extension after it: the runtime, the editor, a dedicated browser, the folder layout, hot reload, and the three places you will spend your debugging life. By the end you will have a working Manifest V3 extension loaded in Chrome and a setup that does not get in your way. TL;DR You need Node and a package manager even for a “simple” extension, because every modern toolchain (TypeScript, bundling, hot reload, cross-browser builds) runs on it. Install the @types/chrome package and a handful of VS Code extensions so your editor autocompletes the extension APIs instead of guessing. Create a separate Chrome profile for development. Loading unpacked extensions into your daily-driver profile is how you leak experiments into real browsing. Vanilla Manifest V3 has no hot reload out of the box. You either accept the reload-by-hand loop or adopt a framework that gives you HMR. There are exactly three debugging surfaces (service worker, popup, content script) and each one is inspected differently. Learn them on day one. Step 1: Install Node and a Package Manager You can technically write an extension with nothing but a text editor and three files. The moment you want TypeScript, a bundler, hot reload, linting, or a one-command cross-browser build, you need Node. Every serious extension toolchain in 2026 assumes it is there. Install the active LTS release (Node 20 or 22 at the time of writing). Do not install Node from a random installer and forget about it. Use a version manager so you can switch versions per project without breaking other work: # macOS / Linux: nvm or the faster fnm nvm install --lts nvm use --lts # Windows: nvm-windows, or fnm (cross-platform) fnm install --lts fnm use lts-latest # Verify node -v # v22. x npm -v Next, pick a package manager. npm ships with Node and is perfectly fine. Most extension frameworks (WXT, Plasmo) lean toward pnpm because it is faster and disk-efficient with the large dependency trees that bundlers pull in: # Enable pnpm via Corepack (bundled with Node) corepack enable corepack prepare pnpm@latest --activate pnpm -v Pick one and stay consistent inside a project, mixing lockfiles is a recipe for “works on my machine. ” Step 2: Set Up VS Code for Extension Work Any editor works, but VS Code has the best out-of-the-box story for the extension APIs. The single most important thing you can do is teach your editor the chrome. * namespace so it autocompletes and type-checks instead of leaving you to memorize method signatures: npm install --save-dev @types/chrome Then add a small set of extensions. These are the ones that earn their place: Extension Why it matters ESLint Catches the silent extension bugs (async listeners, undefined globals) before you load anything Prettier Stops you from arguing with yourself about formatting across . html files Error Lens Surfaces type and lint errors inline, so you see the broken chrome. tabs call without hovering TypeScript (built in) Pair it with @types/chrome for real autocomplete on every API Even Better TOML / JSON Manifest and config files are JSON, schema validation here saves submission rejections A minimal . json that keeps a team honest: { "editor. formatOnSave" : true , "editor. defaultFormatter" : "esbenp. prettier-vscode" , "editor. codeActionsOnSave" : { "source. eslint" : "explicit" }, "typescript. tsdk" : "node_modules/typescript/lib" } If you have never touched the extension APIs before, keep our Manifest V3 cheatsheet open in a tab. It explains every field your editor will start autocompleting. Step 3: Create a Dedicated Chrome Profile This is the step that separates people who enjoy extension development from people who keep “accidentally” running their half-broken extension against their real Gmail. Chrome ships in four release channels. For development you mostly want a clean Stable profile, with Canary as a second browser when you need bleeding-edge APIs or origin trials: Channel Use it for Stable Your default development target, it is what most users run Beta Catching breakage a few weeks before it reaches users Dev Newer APIs that are close to shipping Canary Experimental and origin-trial APIs, updated daily, expect crashes Create a fresh profile so your experiments never touch your personal data: Click your profile avatar in the top-right of Chrome. Choose Add and create a profile named something like “Extension Dev”. This profile should have no real accounts, no synced passwords, and no other extensions installed. Now every unpacked extension you load lives in a sandbox you can wipe and rebuild without consequences. You also get a realistic “new user” environment, which is exactly what you want when you later test onboarding. Step 4: Enable Developer Mode and Load Unpacked In your dev profile: Go to chrome://extensions . Toggle Developer mode on (top-right). Click Load unpacked and select your project folder (the one containing manifest. Three buttons now matter on the extension card: the reload circular arrow (re-reads your files), the service worker link (opens the background DevTools), and Remove . You will press reload more than any other button in this entire process, so note where it is. We cover the full enable-and-inspect flow with screenshots in the build-and-publish walkthrough if you want the visual version. Step 5: Lay Out Your Project Folder How you structure files depends on whether you are going vanilla or using a framework. Here they are side by side so you can see the trade-off. A vanilla Manifest V3 project, the files Chrome loads directly: my-extension/ ├── manifest. json # the entry point Chrome reads ├── background. js # service worker ├── content. js # injected into matching pages ├── popup/ │ ├── popup. js ├── options/ │ └── options. html └── icons/ ├── icon-16. png A WXT project, where you write source and the tool generates the loadable build: my-extension/ ├── wxt. ts # build + manifest config ├── package. json ├── entrypoints/ │ ├── background. ts │ └── popup/ │ ├── index. ts ├── public/ # static assets, icons └── . output/ # generated, this is what you load unpacked The vanilla layout is the right way to learn what Chrome actually requires. The framework layout is the right way to ship , because you stop hand-writing the manifest, get TypeScript and hot reload for free, and can target other browsers from the same source. When you are ready to choose one, we benchmarked the main options in 5 frameworks compared , and WXT gets its own complete guide . Planning to support Firefox and Edge too. Start from our cross-browser quick-start template so the framework layout works on every browser from day one. Step 6: Write a Minimal manifest. json Whatever path you pick, it helps to understand the smallest manifest Chrome will accept. This is a complete, loadable MV3 manifest: { "manifest_version" : 3 , "name" : "My First Extension" , "version" : "0. 0" , "description" : "A starter Manifest V3 extension. " , "action" : { "default_popup" : "popup/popup. html" , "default_title" : "My First Extension" }, "background" : { "service_worker" : "background. js" }, "permissions" : [ "storage" ], "icons" : { "16" : "icons/icon-16. png" , "48" : "icons/icon-48. png" , "128" : "icons/icon-128. png" } } Two rules that save you real time later: Request the smallest permission set that works.
This is a condensed version of a deeper guide. The full article covers additional context and examples.
Worth Bookmarking
If you're working with Chrome extensions, you'll eventually need tools for:
- Generating icons at multiple sizes
- Creating store screenshots that look professional
- Converting MV2 extensions to MV3
- Analyzing bundle size
ExtensionBooster has free versions of all of these. I keep it bookmarked for every extension project.
Top comments (0)