If you've ever built a Chrome Extension with Manifest V3,
you've probably hit at least one of these walls.
I did. Multiple times. Here's what I learned the hard way.
1. Service workers don't persist state
This is the biggest mindset shift from MV2.
Any variable you declare in background.js is gone the moment
Chrome decides to kill the service worker — and it will,
unpredictably.
The fix: never store anything in variables. Use chrome.storage
for everything.
// Wrong
let userSettings = {};
// Right
chrome.storage.local.set({ userSettings });
2. Async messaging silently fails without return true
This one cost me hours of debugging.
When you send a message from popup.js to background.js and
expect an async response, you must return true inside the
onMessage listener — otherwise Chrome closes the message
channel before the response arrives.
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'RUN_ACTION') {
doSomethingAsync()
.then(result => sendResponse({ success: true, data: result }));
return true; // This line is mandatory for async responses
}
});
No error is thrown if you forget it. The response just never
arrives.
3. chrome.alarms requires explicit permission
You add chrome.alarms to your code. Nothing works. No error.
The reason: you forgot to declare "alarms" in manifest.json.
{
"permissions": ["storage", "activeTab", "alarms"]
}
Always declare every API you use in permissions. Chrome won't
tell you what's missing.
4. The popup closes on every outside click
This seems obvious in hindsight, but it changes how you design
your UX completely.
Any interaction that requires the user to click outside the
popup — selecting text on a page, switching tabs — closes it
immediately. Design your extension assuming the popup is
temporary, not persistent.
What I built after learning all this
After dealing with these issues on every new project, I put
together a boilerplate that handles all of it out of the box:
popup, background worker, content script, storage and messaging
— all wired together and ready to go.
It's called MG Launch and it's free right now if you want to
try it: macigiancarlo.gumroad.com/l/dckcz
What issues did you run into building MV3 extensions?
Drop them in the comments — would love to compare notes.
Top comments (0)