Chrome Extension manifest.json: The Complete Guide to Every Field You'll Actually Use
By BasharathThe manifest.json file is the brain of your Chrome extension. It's the first file Chrome reads when loading your extension, and it determines everything from what your extension can do to how it appears in the browser. Get it wrong, and your extension won't even load. Get it right, and you unlock the full potential of Chrome's extension API.
But here's the thing: the manifest file has evolved over the years, and if you're reading outdated tutorials, you might be using deprecated fields or missing out on new features. In this guide, we'll break down every field you'll actually use in Manifest V3 (the current standard), explain what each one does, and show you practical examples.
What is manifest.json?
Think of manifest.json as your extension's ID card and instruction manual combined. It tells Chrome:
What your extension is called and what it does
Which permissions it needs
What files to load and when
How users interact with it
What version of the manifest format you're using
Every Chrome extension must have a manifest.json file in its root directory. Without it, Chrome won't recognize your folder as an extension.
Manifest V2 vs V3: What's the Difference?
Chrome has had three versions of the manifest format, but only two matter today:
Manifest V2 (Deprecated)
Used from 2012 to 2022. If you see "manifest_version": 2 in tutorials, that code is outdated. Chrome stopped accepting new V2 extensions in 2022 and will fully disable them by 2024.
Manifest V3 (Current Standard)
Released in 2021 and required for all new extensions since 2022. V3 brings better security, performance, and privacy. Key changes include:
Background pages → Service workers
Blocking web requests → Declarative net request
Better permission handling
Improved security model
Always use Manifest V3 for new extensions. That's what we'll cover in this guide.
The Essential Fields (Required)
These fields are mandatory. Your extension won't load without them.
1. manifest_version
"manifest_version": 3
What it does: Tells Chrome which version of the manifest format you're using.
Always use: 3 for new extensions. Never use 2 anymore.
2. name
"name": "My Awesome Extension"What it does: The name of your extension as it appears in the Chrome Web Store and extensions page.
Best practices:
Keep it under 45 characters
Make it descriptive and searchable
Avoid generic names like "Extension" or "Tool"
Example: "Todo Master - Task Manager" is better than "Todo Extension"
3. version
"version": "1.0.0"What it does: Your extension's version number. Chrome uses this to detect updates.
Format: Must be 1-4 numbers separated by dots (e.g., 1.0, 1.2.3, 2.0.0.1)
Best practices:
Start with
1.0or1.0.0Increment for each update (1.0 → 1.1 → 2.0)
Major changes = increment first number
Minor updates = increment second number
Bug fixes = increment third number
Important Fields (Highly Recommended)
These aren't technically required, but you'll almost always need them.
4. description
"description": "A simple and elegant todo list extension for managing your daily tasks"What it does: Brief description of what your extension does. Appears in the Chrome Web Store and extensions page.
Best practices:
Maximum 132 characters
Be specific about what it does
Include keywords for Chrome Web Store SEO
Don't use generic descriptions
5. icons
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}What it does: Specifies icon files for different display sizes.
Sizes explained:
16x16: Favicon on extension pages
48x48: Extensions management page
128x128: Chrome Web Store and installation dialog
Best practices:
Always provide at least a 128x128 icon
Use PNG format with transparency
Keep designs simple and recognizable at small sizes
Can use a single icon for all sizes:
"default_icon": "icon.png"
6. action
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"24": "icons/icon24.png",
"32": "icons/icon32.png"
},
"default_title": "Click to open Todo List"
}What it does: Defines the toolbar button and what happens when users click it.
Fields inside action:
default_popup: HTML file that opens when icon is clicked
default_icon: Icon shown in toolbar (can be string or object with sizes)
default_title: Tooltip text when hovering over icon
When to use: Almost every extension has an action. Omit it only if your extension runs entirely in the background.
Permission Fields
Permissions tell Chrome what APIs and features your extension needs access to.
7. permissions
"permissions": [
"storage",
"activeTab",
"notifications"
]What it does: Lists Chrome APIs your extension needs. Users must approve these during installation.
Common permissions:
storage: Access to
chrome.storageAPI (local data storage)activeTab: Access to currently active tab when user invokes extension
tabs: Access to tab information (URLs, titles)
notifications: Show system notifications
alarms: Schedule code to run periodically
scripting: Inject scripts into web pages
cookies: Read and modify cookies
bookmarks: Access bookmark data
history: Access browsing history
Best practices:
Only request permissions you actually need
More permissions = users less likely to install
Use
activeTabinstead oftabswhen possible (requires less permission)
8. host_permissions
"host_permissions": [
"https://*/*",
"http://*/*",
"*://example.com/*"
]What it does: Specifies which websites your extension can interact with.
When to use: When your extension needs to run code on specific websites or all websites.
Patterns:
"*://*/*": All URLs (HTTP and HTTPS)"https://*/*": All HTTPS URLs only"*://google.com/*": All Google.com pages"<all_urls>": All URLs including file:// and ftp://
Best practices:
Be as specific as possible
Don't request all URLs if you only need specific sites
Requesting all URLs triggers a warning during installation
9. optional_permissions
"optional_permissions": [
"geolocation",
"clipboardWrite"
],
"optional_host_permissions": [
"https://api.example.com/*"
]What it does: Permissions that can be granted later, not during installation.
When to use: For features users might not use immediately, reducing initial permission requests.
Example use case: A translation extension might not need API access until user enables a premium feature.
Content Scripts
10. content_scripts
"content_scripts": [
{
"matches": ["https://*/*", "http://*/*"],
"js": ["content.js"],
"css": ["content.css"],
"run_at": "document_idle"
}
]What it does: Injects JavaScript and CSS files directly into web pages.
Fields:
matches: URL patterns where scripts should run (required)
js: Array of JavaScript files to inject
css: Array of CSS files to inject
run_at: When to inject
document_start: Before page loadsdocument_end: After DOM loads, before imagesdocument_idle: After page fully loads (default)
When to use: When your extension modifies web pages (ad blockers, theme changers, page enhancers)
Example use case: Dark mode extension that injects CSS to make all websites dark. Clipboard extension that uses Content Script to display copied text within the page.
Background Scripts (Service Workers)
11. background
"background": {
"service_worker": "background.js"
}What it does: Runs a service worker in the background to handle events, API calls, and long-running tasks.
Important notes:
Manifest V3 uses service workers, not background pages
Service workers are event-driven and don't run continuously
No DOM access in service workers (no
documentorwindow)Only one file allowed (unlike content_scripts which can have multiple)
When to use:
Handling extension events (installation, updates)
Managing state across tabs
Making API calls
Processing messages from content scripts
Example use case: Opening a tab when users click the extension icon.
// background.js
chrome.action.onClicked.addListener((tab) => {
chrome.tabs.create({ url: 'popup.html' });
});Page Overrides
12. chrome_url_overrides
"chrome_url_overrides": {
"newtab": "newtab.html"
}What it does: Replaces Chrome's default pages with your custom pages.
Can override:
newtab: New tab page
bookmarks: Bookmarks page (
chrome://bookmarks)history: History page (
chrome://history)
Limitation: Can only override ONE page per extension.
When to use: Custom new tab page extensions (like Momentum, Infinity New Tab)
Side Panel
13. side_panel
"side_panel": {
"default_path": "sidepanel.html"
}What it does: Opens your extension in Chrome's side panel (left or right side of browser).
Requires: "sidePanel" permission
When to use: Extensions that need to stay visible while users browse (notes, reading lists, bookmarks)
Example manifest:
{
"manifest_version": 3,
"name": "Side Panel Extension",
"permissions": ["sidePanel"],
"side_panel": {
"default_path": "panel.html"
}
}Options and Settings
14. options_page
"options_page": "options.html"What it does: Creates a settings page accessible by right-clicking your extension icon and selecting "Options".
When to use: Your extension has user preferences, settings, or configuration.
Alternative: Use options_ui for embedded options in Chrome's extension management page:
"options_ui": {
"page": "options.html",
"open_in_tab": false
}open_in_tab: false: Opens in an embedded dialog (recommended)
open_in_tab: true: Opens in a full tab
Web Accessible Resources
15. web_accessible_resources
"web_accessible_resources": [
{
"resources": ["images/*", "styles.css"],
"matches": ["https://*/*"]
}
]What it does: Makes extension files accessible to web pages.
When to use:
Content scripts need to inject images or assets from your extension
Web pages need to load resources from your extension
Showing extension images on modified web pages
Security note: Only expose files that absolutely need to be public.
Commands (Keyboard Shortcuts)
16. commands
"commands": {
"open-todo": {
"suggested_key": {
"default": "Ctrl+Shift+T",
"mac": "Command+Shift+T"
},
"description": "Open todo list"
},
"_execute_action": {
"suggested_key": {
"default": "Ctrl+Shift+E"
}
}
}What it does: Defines keyboard shortcuts for your extension.
Special commands:
executeaction: Triggers the default action (opens popup)
executebrowser_action: Same as above (legacy name)
Best practices:
Use
Ctrl+Shift+[Letter]formatSeparate Mac shortcuts with
Commandinstead ofCtrlDon't use already common shortcuts
Keep descriptions short and clear
Content Security Policy
17. content_security_policy
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'"
}What it does: Defines security restrictions for your extension's pages.
Default policy in V3: Very strict, doesn't allow inline scripts or eval().
Most developers: Don't need to change this. The default is secure and sufficient.
When to modify: Only if you need to load external scripts (not recommended for security).
Internationalization
18. default_locale
"default_locale": "en"What it does: Specifies the default language when using internationalization (i18n).
Required when: You have a _locales folder with translation files.
Example structure:
my-extension/
├── _locales/
│ ├── en/
│ │ └── messages.json
│ ├── es/
│ │ └── messages.jsonWhen to use: Building multilingual extensions.
Other Useful Fields
19. author
"author": "Your Name"or
"author": {
"email": "[email protected]"
}What it does: Identifies the extension's creator (metadata only).
20. homepage_url
"homepage_url": "https://yourwebsite.com"What it does: Links to your extension's website or documentation.
21. minimum_chrome_version
"minimum_chrome_version": "88"What it does: Specifies the minimum Chrome version required to run your extension.
When to use: If you're using newer APIs not available in older Chrome versions.
22. externally_connectable
"externally_connectable": {
"matches": ["https://yourwebsite.com/*"]
}What it does: Allows specific websites to communicate with your extension using chrome.runtime.sendMessage().
When to use: Building extensions that interact with your website.
A Complete Example Manifest
Here's what a real-world todo list extension manifest looks like with commonly used fields:
{
"manifest_version": 3,
"name": "Todo Master - Task Manager",
"version": "1.2.0",
"description": "A beautiful and simple todo list extension for managing daily tasks",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"action": {
"default_popup": "popup.html",
"default_icon": "icons/icon48.png",
"default_title": "Open Todo List"
},
"permissions": [
"storage",
"alarms",
"notifications"
],
"background": {
"service_worker": "background.js"
},
"options_ui": {
"page": "options.html",
"open_in_tab": false
},
"commands": {
"open-todo": {
"suggested_key": {
"default": "Ctrl+Shift+T",
"mac": "Command+Shift+T"
},
"description": "Open todo list"
}
},
"author": "Your Name",
"homepage_url": "https://yourwebsite.com"
}Common Mistakes and How to Avoid Them
Mistake 1: Using Manifest V2
Problem: Your extension won't be accepted to the Chrome Web Store.
Solution: Always start with "manifest_version": 3
Mistake 2: Requesting Too Many Permissions
Problem: Users won't install your extension because it looks suspicious.
Solution: Only request permissions you actually use. Test without unnecessary permissions.
Mistake 3: Wrong File Paths
Problem: Chrome can't find your HTML/JS/CSS files.
Solution: Double-check all paths in manifest. They're relative to the manifest.json file location.
Mistake 4: Invalid Version Numbers
Problem: Extension won't load.
Solution: Version must be 1-4 dot-separated integers (e.g., 1.0, 1.2.3, not 1.2.3.4.5)
Mistake 5: Missing Icons
Problem: Extension loads but looks unprofessional.
Solution: Always include at least a 128x128 icon, even if it's just a simple design.
Quick Reference: Which Fields Do I Need?
Minimum viable extension:
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0"
}Popup extension: Add action with default_popup
Extension that modifies web pages: Add content_scripts and host_permissions
Extension that runs in background: Add background with service_worker
Extension with settings: Add options_page or options_ui
Extension that stores data: Add "storage" to permissions
Key Takeaways
The manifest.json file is simple once you understand what each field does. Most extensions only use 5-10 fields total. Start with the required fields (manifest_version, name, version), add the fields for your extension type (action, content_scripts, etc.), and request only the permissions you need.
Remember: Chrome is very strict about the manifest format. One wrong comma or quote, and your extension won't load. Use a JSON validator if you're getting errors, and always test your manifest by loading it as an unpacked extension before publishing.
Now you have a complete reference for every manifest field you'll actually use. Bookmark this guide and refer back whenever you're building a new Chrome extension!
Written by Basharath
Chrome extension developer sharing insights, tutorials, and best practices for building better browser extensions.
