How to Create a Browser Extension manifest.json: A Complete Guide for Beginners

A browser extension manifest.json file declares the extension's metadata, permissions, background service worker, and UI entry points using Manifest V3 schema.

The manifest.json file serves as the central configuration hub that tells Chrome, Edge, or Firefox how to load and run your extension. In the microsoft/Web-Dev-For-Beginners curriculum, the extension project lives under 5-browser-extension/, with a production-ready manifest located at 5-browser-extension/start/dist/manifest.json.

What the manifest.json File Configures

The manifest defines every operational aspect of your extension, from network permissions to user interface components.

Section Purpose Example from the Repository
manifest_version Declares the schema version browsers must validate against. Modern browsers require version 3. "manifest_version": 3
name Human-readable title displayed in the extensions manager. "name": "My Carbon Trigger"
version Semantic version for update management. "version": "0.1.0"
host_permissions URL patterns the extension may access for API calls. "host_permissions": ["<all_urls>"]
background Declares the service worker script handling background events. "background": { "service_worker": "background.js" }
action Defines the popup HTML displayed when users click the toolbar icon. "action": { "default_popup": "index.html" }

Step-by-Step Guide to Create a Browser Extension manifest.json

Follow these steps to construct a valid Manifest V3 configuration file for the Carbon Trigger extension or any new project.

1. Initialize the File

Create a file named manifest.json in your extension's root or distribution folder. In the Web-Dev-For-Beginners project, this file resides in 5-browser-extension/start/dist/ after the build process.

2. Declare Manifest Version and Metadata

Set the schema version to 3 and provide essential identification details.

{
  "manifest_version": 3,
  "name": "My Carbon Trigger",
  "version": "0.1.0",
  "description": "Shows regional carbon intensity using the CO₂ Signal API"
}

3. Configure Network Permissions

Add host_permissions to specify which domains your extension may access. For development, <all_urls> permits access to any API endpoint.

  "host_permissions": ["<all_urls>"],

4. Register the Background Service Worker

Declare the background script that handles events when the browser is running. In 5-browser-extension/start/dist/background.js, this script manages API calls and storage.

  "background": {
    "service_worker": "background.js"
  },

5. Define the Popup User Interface

Use the action key to specify which HTML file renders when users click the extension icon.

  "action": {
    "default_popup": "index.html"
  }

6. Add Extension Icons (Optional)

Include icon assets for the toolbar and Chrome Web Store listings.

  "icons": {
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

Complete manifest.json Example

Here is the full configuration file used in the microsoft/Web-Dev-For-Beginners extension project, located at 5-browser-extension/start/dist/manifest.json:

{
  "manifest_version": 3,
  "name": "My Carbon Trigger",
  "version": "0.1.0",
  "description": "Shows regional carbon intensity using the CO₂ Signal API",
  "host_permissions": ["<all_urls>"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "index.html"
  },
  "icons": {
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

Project Architecture and File Relationships

The manifest.json file acts as the bridge between your source code and the browser's extension runtime. In the Web-Dev-For-Beginners curriculum, the build pipeline generates a dist/ folder containing all runtime assets.


project-root/
├─ dist/                      # Build output (load this folder in Chrome)

│   ├─ manifest.json          ← Browser entry point
│   ├─ index.html             ← Popup UI (referenced by manifest)
│   ├─ background.js          ← Service worker (referenced by manifest)
│   └─ main.js                ← Bundled application logic
├─ src/                       # Source files you edit

│   └─ index.js               ← Development entry point
├─ package.json               # Build scripts and dependencies

└─ webpack.config.js          # Bundles src/ → dist/

When you load the unpacked extension in Chrome or Edge, you select the dist/ folder. The browser immediately reads manifest.json to locate background.js and index.html.

Practical Code Examples

Loading the Extension in Development Mode

After running the build command, load your extension into Chrome to test the manifest.json configuration:


# Generate the dist/ folder with manifest.json

npm run build

# Then in Chrome:

# 1. Navigate to chrome://extensions

# 2. Enable "Developer mode" (toggle in top right)

# 3. Click "Load unpacked"

# 4. Select the 5-browser-extension/start/dist folder

Background Script Implementation

The background.js file referenced in manifest.json handles API requests and browser events:

// background.js (service worker)
chrome.runtime.onInstalled.addListener(() => {
  console.log('Carbon Trigger extension installed');
});

// Fetch carbon intensity data using host_permissions declared in manifest
async function fetchCarbonData(regionCode) {
  const response = await fetch(`https://api.co2signal.com/v1/latest?region=${regionCode}`, {
    headers: { 'auth-token': 'YOUR_API_KEY' }
  });
  return response.json();
}

The index.html popup communicates with the background service worker to display data:

// src/index.js (bundled into dist/main.js)
document.querySelector('.search-btn').addEventListener('click', async (e) => {
  e.preventDefault();
  const region = document.querySelector('.region-name').value;
  
  // Call background script or API directly
  const data = await fetchCarbonData(region);
  
  document.querySelector('.my-region').textContent = region;
  document.querySelector('.carbon-usage').textContent = data.carbonIntensity;
});

Key Repository Files

These files from the microsoft/Web-Dev-For-Beginners repository demonstrate the complete extension implementation:

File Purpose Location
manifest.json Core configuration declaring permissions and entry points 5-browser-extension/start/dist/manifest.json
background.js Service worker handling background tasks and API calls 5-browser-extension/start/dist/background.js
index.html Popup interface displayed when clicking the extension icon 5-browser-extension/start/dist/index.html
index.js Source file containing popup logic, bundled into main.js 5-browser-extension/start/src/index.js
package.json NPM configuration with build scripts and dependencies 5-browser-extension/start/package.json
README.md Curriculum documentation for the browser extension lesson 5-browser-extension/README.md

Summary

  • The manifest.json file is mandatory for every browser extension and defines metadata, permissions, and entry points using the Manifest V3 schema.
  • Manifest version 3 requires a service_worker for background scripts instead of persistent background pages, improving performance and security.
  • Host permissions must be explicitly declared to allow API calls to external domains like CO₂ Signal.
  • The action key specifies the popup HTML file that renders when users click the extension toolbar icon.
  • In the microsoft/Web-Dev-For-Beginners curriculum, the complete working manifest resides at 5-browser-extension/start/dist/manifest.json.

Frequently Asked Questions

What is the difference between Manifest V2 and Manifest V3?

Manifest V3 is the current standard required by Chrome, Edge, and Firefox for new extensions. The primary difference is the replacement of persistent background pages with service workers that run only when needed, reducing resource consumption. V3 also requires explicit host_permissions for network requests and removes certain capabilities like remotely hosted code for security reasons.

Where should I place the manifest.json file in my project?

Place manifest.json in the root of the folder you load as an unpacked extension. In the Web-Dev-For-Beginners project structure, this is the dist/ directory (5-browser-extension/start/dist/manifest.json). If you use a bundler like Webpack, ensure the build process copies the manifest into the output folder alongside index.html and background.js.

Why does my extension need host_permissions?

Host permissions tell the browser which external domains your extension is allowed to access via fetch() or XMLHttpRequest. Without declaring "host_permissions": ["<all_urls>"] or specific domains like ["https://api.co2signal.com/*"], the browser blocks network requests for security reasons. In the Carbon Trigger extension, these permissions enable the background script to retrieve carbon intensity data from external APIs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →