DEV Community

Weather Clock Dash
Weather Clock Dash

Posted on

Firefox Extension Manifest V3 vs V2: What Actually Changed

Firefox Extension Manifest V3 vs V2: What Actually Changed

If you've been following Chrome's controversial Manifest V3 migration, you might be wondering: does Firefox have the same MV3? The answer is: yes and no. Firefox has its own implementation of Manifest V3, and it's meaningfully different from Chrome's.

The Short Version

  • Firefox MV3 supports both MV2 and MV3 extensions
  • Firefox's MV3 is less restrictive than Chrome's
  • Firefox still supports browser.webRequest blocking in MV3
  • Service workers replace background pages (same as Chrome)

What Changed: Background Scripts

MV2 (background page):

// manifest.json
{
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}
Enter fullscreen mode Exit fullscreen mode

MV3 (service worker):

// manifest.json
{
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  }
}
Enter fullscreen mode Exit fullscreen mode

The key implication: service workers don't persist state in memory. They're event-driven and can be terminated at any time. Code like this breaks:

// ❌ This DOESN'T work in MV3 service workers
let cachedData = {}; // Lost when service worker terminates!

chrome.tabs.onActivated.addListener(() => {
  if (cachedData.weather) {
    // cachedData might be {} if SW was terminated
  }
});
Enter fullscreen mode Exit fullscreen mode

Fix: Use browser.storage.session (MV3 only) or browser.storage.local:

// ✅ This works in MV3
async function getCachedData() {
  const { cachedData } = await browser.storage.session.get('cachedData');
  return cachedData || {};
}

async function setCachedData(data) {
  await browser.storage.session.set({ cachedData: data });
}
Enter fullscreen mode Exit fullscreen mode

What Changed: Content Security Policy

MV2: More permissive CSP

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
Enter fullscreen mode Exit fullscreen mode

MV3: Stricter — no unsafe-eval, no remote scripts

"content_security_policy": {
  "extension_pages": "script-src 'self'; object-src 'self'"
}
Enter fullscreen mode Exit fullscreen mode

This means: no more eval(), no more loading scripts from external CDNs directly. You must bundle all JavaScript.

What Changed: Action API

MV2: Separate browser_action and page_action

MV3: Unified action

// MV2
"browser_action": {
  "default_icon": "icon.png",
  "default_popup": "popup.html"
}

// MV3
"action": {
  "default_icon": "icon.png",
  "default_popup": "popup.html"
}
Enter fullscreen mode Exit fullscreen mode

In code:

// MV2
browser.browserAction.setBadgeText({ text: '5' });

// MV3
browser.action.setBadgeText({ text: '5' });
Enter fullscreen mode Exit fullscreen mode

What Firefox Kept (That Chrome Removed)

This is the important difference: Firefox MV3 still allows blocking webRequest.

Chrome replaced blocking webRequest with declarativeNetRequest, which is less powerful but more privacy-preserving. Firefox offers both:

// Firefox MV3 — still works!
browser.webRequest.onBeforeRequest.addListener(
  (details) => {
    if (details.url.includes('tracker.example.com')) {
      return { cancel: true };
    }
  },
  { urls: ['<all_urls>'] },
  ['blocking']
);
Enter fullscreen mode Exit fullscreen mode

This matters for ad blockers and privacy tools — uBlock Origin works on Firefox MV3 because of this.

Migrating a New Tab Extension

For new tab extensions like Weather & Clock Dashboard, the migration is mostly straightforward:

// Before (MV2)
{
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  "browser_action": {},
  "chrome_url_overrides": {
    "newtab": "newtab.html"
  }
}
Enter fullscreen mode Exit fullscreen mode
// After (MV3)
{
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js",
    "type": "module"  // Optional: enables ES modules
  },
  "action": {},
  "chrome_url_overrides": {
    "newtab": "newtab.html"
  }
}
Enter fullscreen mode Exit fullscreen mode

The newtab override itself doesn't change between MV2 and MV3 — that part is stable.

Should You Migrate?

For Firefox: MV2 still works and Mozilla has said they'll support it. Migrating to MV3 is optional for now.

For Chrome: MV2 is being deprecated. If you also publish to the Chrome Web Store, migrating is necessary.

For new extensions: Start with MV3. It's the future-proof choice.


For the Weather & Clock Dashboard, I'm currently on MV2 since the extension is Firefox-only. Migration to MV3 is on the roadmap.

Install the extension: Weather & Clock Dashboard on AMO

Questions about MV3 migration? Drop them in the comments!


Part of a series on building Firefox browser extensions.

firefox #javascript #webdev #browserextension

Top comments (0)