Chrome Extension Development Setup: The 2026 Starter Guide | ExtensionBooster
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.fixAll.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.json).
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
└── icon-48.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.1",
"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
storageand add others only when a feature needs them. - Register background listeners synchronously. A service worker that adds
chrome.onMessageinside 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! 🚀
Comments
No comments yet. Start the discussion.