Chrome extensions in 2026 are nothing like Chrome extensions in 2018. Manifest V3 reshaped the architecture, killed long-running background pages, and added a service-worker model that surprises you the first time it sleeps mid-execution. The tooling, fortunately, has caught up.
This guide is the working approach for shipping a Chrome extension today.
What changed in 2026
Manifest V2 is fully sunset. Manifest V3 is the only path.
- Service workers, not background pages. They terminate aggressively. Persist state externally.
- Declarative net request replaces webRequest blocking. Content blockers had to redesign.
- Side panels, action APIs, offscreen documents. New surface area worth knowing.
How we picked the stack
Five components every modern extension needs.
- A bundler that understands MV3 (wxt or vite-plugin-web-extension)
- TypeScript (the API surface is huge)
- A persistent storage layer (
chrome.storage.local or IndexedDB)
- Message passing helpers (typed wrappers save weeks)
- A test setup (Playwright with extension loading)
1. Use wxt or Plasmo as the framework
The two real frameworks for MV3 extensions in 2026 are wxt and Plasmo. Both handle the manifest, hot reload, framework integration (React/Vue/Svelte), and packaging. Trying to do MV3 with raw Webpack and a hand-written manifest is a slow tax with no upside.
The trade-off: an extra abstraction. Both frameworks are thin enough that you can eject if you ever need to.
2. Design for service worker lifecycle
The single biggest source of MV3 bugs is treating the background service worker like a long-running process. It is not. Chrome may terminate it after 30 seconds of inactivity. Anything you store in module-level variables disappears when it sleeps.
The fix: persist any state you care about to chrome.storage.local or chrome.storage.session. Reload it at the top of each event handler. Use alarms (chrome.alarms) for periodic tasks, not setInterval.
3. Content scripts, side panel, popup
Three UI surfaces. Pick the right one.
- Popup — small, transient UI from the toolbar icon.
- Side panel — persistent UI in a panel. Better than popups for anything sustained.
- Content script — code injected into a page. For modifying the actual web page.
Comparison: Chrome extension stacks in April 2026
| Stack |
Setup time |
DX |
Best for |
| wxt |
Fast |
Excellent |
Default for new extensions |
| Plasmo |
Fast |
Excellent |
React-heavy extensions |
| Vite + plugin |
Medium |
Good |
Custom setups |
| Raw MV3 |
Slow |
Painful |
Learning the API only |
Common mistakes to avoid
Storing state in service worker memory. It will be gone the next time you check. Use chrome.storage.
Asking for too many permissions. Each permission widens the install warning and can get your extension blocked from the Chrome Web Store. Ask for the minimum, use optional permissions for the rest.
Skipping cross-browser testing. Firefox and Edge support MV3 but with subtle differences. If you advertise multi-browser, test multi-browser.
FAQ
Can I share code between Chrome and Firefox extensions?
Yes — wxt and Plasmo both target multiple browsers from one source. Some APIs differ; their abstractions handle most of it.
Do I need a developer account?
Yes — $5 one-time fee for the Chrome Web Store. Be prepared for a 1–3 day review on first publish.
How do I add AI features to an extension?
Either bundle a small model with chrome.ai (Gemini Nano on supported devices) or call a remote API. Watch CSP rules carefully for the latter.
Where to go next
For related guides see How to build a VS Code extension in 2026, Best VPNs for restricted countries in 2026, and AI privacy guide.