Safari WebExtensions: Manifest V2 vs. Manifest V3 Support

This article provides a direct comparison of Manifest V2 (MV2) and Manifest V3 (MV3) support within the Apple Safari web browser. As the web extension ecosystem transitions from MV2 to MV3 to improve privacy, security, and performance, Safari has implemented support for both standards—starting with MV2 in Safari 14 and introducing MV3 in Safari 15.4. Because Apple prioritizes user privacy and battery life, Safari’s implementation of MV2 already shared several traits with the modern MV3 standard, making the transition in Safari unique compared to Chromium-based browsers. Below are the specific technical differences between MV2 and MV3 within Safari's WebExtensions architecture.

Background Processing

The way extensions run tasks in the background is a primary architectural change between the two manifest versions.

  • Manifest V2: Uses background pages defined via the background.scripts or background.page keys. While MV2 allows persistent background pages on desktop browsers, Safari on iOS never supported persistent background pages due to memory constraints, forcing developers to use non-persistent event pages.
  • Manifest V3: Replaces background pages entirely with Service Workers, defined using the background.service_worker key. Service Workers are strictly event-driven, terminate when not in use, and do not have access to the DOM or the window object.

Network Request Modification

Content blocking and network request modification work very differently across the two versions, though Safari’s MV2 implementation was already restrictive.

  • Manifest V2: Relies on the webRequest API. However, unlike Chrome and Firefox, Safari never supported the webRequestBlocking capability in MV2. Extension developers could observe network requests in Safari using MV2, but they could not intercept, block, or modify them on the fly using this API.
  • Manifest V3: Introduces the declarativeNetRequest API. Instead of the extension intercepting requests dynamically, it provides Safari with a list of rules. Safari compiles these rules into its native WebKit Content Blocker engine. This allows MV3 extensions in Safari to block content, strip cookies, and redirect requests without the extension needing read access to the user's network traffic.

Code Execution and Security

Manifest V3 enforces stricter security boundaries regarding how and where code is executed compared to Manifest V2.

  • Script Injection: In MV2, extensions inject JavaScript and CSS into web pages using browser.tabs.executeScript() and browser.tabs.insertCSS(). In MV3, these methods are removed from the tabs API and moved to the new scripting API, requiring the "scripting" permission and using browser.scripting.executeScript() and browser.scripting.insertCSS().
  • Remotely Hosted Code: Safari's MV2 implementation allows some flexibility with Content Security Policy (CSP) definitions, permitting the execution of remotely hosted code and strings evaluated via eval(). In MV3, Safari strictly forbids remotely hosted code. All executable logic must be bundled within the extension package submitted to the App Store, and eval() is blocked by default.

Toolbar Actions

The configuration for extension icons in the Safari toolbar is simplified in the newer manifest.

  • Manifest V2: Splits toolbar configurations into browser_action (for extensions that apply to all pages) and page_action (for extensions that apply only to specific pages). Historically, Safari treated both nearly identically in the browser UI.
  • Manifest V3: Deprecates both keys and unifies them into a single action key in the manifest.json file, pairing it with the browser.action API.

Host Permissions

How an extension declares and requests access to specific websites is separated in Manifest V3.

  • Manifest V2: API permissions (like "storage" or "tabs") and website URL permissions (like "*://*.example.com/*") are grouped together in the same permissions array, or optional_permissions array.
  • Manifest V3: Website URLs must be removed from the standard permissions array and placed into a dedicated host_permissions or optional_host_permissions array.

Note on Safari's Permission Model: Regardless of whether an extension uses MV2 or MV3, Safari treats all host permissions as optional at runtime. Users are always prompted to grant "Always Allow" or "Allow for One Day" on a per-site basis. MV3 brings the rest of the browser industry in line with the permission model Safari had already established in MV2.

Web Accessible Resources

Exposing extension assets (like images or scripts) to web pages requires more explicit definitions in MV3.

  • Manifest V2: Defines web_accessible_resources as a simple array of file path strings. Any website can access the listed resources if it knows the URL.
  • Manifest V3: Requires web_accessible_resources to be an array of objects. Each object must specify both the resources (the file paths) and the matches (an array of specific URLs or origins that are allowed to access those files), preventing arbitrary websites from fingerprinting the user's installed Safari extensions.

Promises Support

  • Manifest V2: When using the chrome.* namespace in Safari, asynchronous APIs require callback functions. Promises are only natively supported in MV2 if the developer uses the browser.* namespace.
  • Manifest V3: Safari supports JavaScript Promises across both the browser.* and chrome.* namespaces for almost all asynchronous API methods, eliminating the need for callback functions or external polyfill libraries.