Manifest V2 to V3 migration guide covering background page to service worker, API changes, webRequest to declarativeNetRequest, remote code removal, executeScript changes, and persistence patterns. Use when upgrading extensions to Manifest V3.
View on GitHubfrancanete/fran-marketplace
chrome-extension-expert
chrome-extension-expert/skills/migration-guide/SKILL.md
January 20, 2026
Select agents to install to:
npx add-skill https://github.com/francanete/fran-marketplace/blob/main/chrome-extension-expert/skills/migration-guide/SKILL.md -a claude-code --skill migration-guideInstallation paths:
.claude/skills/migration-guide/# Manifest V2 to V3 Migration Guide
## Overview of Changes
| Feature | Manifest V2 | Manifest V3 |
|---------|-------------|-------------|
| Background | Persistent page | Service worker |
| Remote code | Allowed | Forbidden |
| Web requests | webRequest API | declarativeNetRequest |
| Host permissions | In permissions | Separate field |
| Content scripts | executeScript string | executeScript files/func |
| CSP | Customizable | Restricted |
| Action | browser_action/page_action | action |
---
## Manifest Changes
### Basic Manifest Update
**MV2:**
```json
{
"manifest_version": 2,
"name": "My Extension",
"version": "1.0",
"browser_action": {
"default_popup": "popup.html",
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"permissions": [
"tabs",
"storage",
"*://*.example.com/*"
]
}
```
**MV3:**
```json
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0",
"action": {
"default_popup": "popup.html",
"default_icon": "icon.png"
},
"background": {
"service_worker": "background.js",
"type": "module"
},
"permissions": [
"tabs",
"storage"
],
"host_permissions": [
"*://*.example.com/*"
]
}
```
### Key Changes
1. `browser_action` / `page_action` → `action`
2. `background.scripts` → `background.service_worker`
3. Host permissions moved to `host_permissions`
4. Add `"type": "module"` for ES modules
---
## Background Page → Service Worker
### Key Differences
| Background Page | Service Worker |
|-----------------|----------------|
| Persistent (optional) | Always terminates |
| DOM access | No DOM |
| window object | No window |
| localStorage | No localStorage |
| XMLHttpRequest | fetch only |
| setTimeout reliable | setTimeout may not fire |
### Migration Steps
**1. Remove DOM dependencies:**
```javascript
// MV2 - Using DOM
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html