DEV Community

Quang Phan
Quang Phan

Posted on

Chrome Extension Development Setup: The 2026 Starter Guide | ExtensionBooster

The Chrome extension landscape has shifted significantly. Here's what's working.

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. Every permission you add can trigger a stronger Web Store warning and a slower review. Start with storage and add others only when a feature needs them. Register background listeners synchronously. A service worker that adds chrome. onMessage inside an async callback silently misses events. This single mistake causes more “my extension randomly stops working” reports than any other, and we break it down in the service worker debugging guide . For a field-by-field reference (CSP, host_permissions , side panel, commands), the Manifest V3 cheatsheet covers every key. For the bigger picture of how the manifest, service worker, content scripts, and messaging fit together, read the architecture fundamentals . Step 7: Get Hot Reload Working Here is the truth nobody tells beginners: vanilla Manifest V3 has no hot reload. Edit a file, then go to chrome://extensions and click reload, then reopen the popup. For content scripts you also have to refresh the host page. It works, but it is tedious, and it gets old around the fiftieth reload of the day. You have two ways out: Accept the manual loop while learning. It is honestly fine for your first extension and forces you to understand what a “reload” actually does. Adopt a framework with HMR the moment the loop annoys you

The Key Takeaway

This is the kind of content that separates quick learners from production-ready developers. Whether you're building your first extension or optimizing an existing one, these patterns save hours of frustration.

Level Up Your Extension Development

Looking for the complete toolkit?

🔥 ExtensionBooster — Free developer tools for Chrome extension builders:

Extension Icons Generator — Resize your icon to every required size in seconds
Screenshot Maker — Produce polished store screenshots that convert

MV2 to MV3 Converter — Modernize your legacy extension with one click
Bundle Analyzer — Find and eliminate the bloat slowing down your extension

These are the tools working developers use daily to ship faster and smarter.

Why This Matters

Chrome extensions are experiencing a renaissance in 2026. With Manifest V3 now mandatory and the Chrome Web Store tightening review standards, the bar for quality has never been higher.

Building on proven patterns means:

  • Faster development cycles
  • Cleaner code that passes store review
  • Better user experience and retention
  • Less time debugging, more time shipping

Start Building

The gap between a good extension and a great one is often just knowing the right approach. Bookmark this, share it with fellow developers, and when you're ready to level up your workflow, check out the full toolkit at ExtensionBooster.

Happy building! 🚀

Top comments (0)