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

> Learn to create a browser extension manifest.json file. Understand metadata, permissions, and UI entry points using the Manifest V3 schema. Start building your extension today.

- Repository: [Microsoft/Web-Dev-For-Beginners](https://github.com/microsoft/Web-Dev-For-Beginners)
- Tags: how-to-guide
- Published: 2026-02-27

---

**A browser extension [`manifest.json`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/manifest.json) file declares the extension's metadata, permissions, background service worker, and UI entry points using Manifest V3 schema.**

The [`manifest.json`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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.

```json
{
  "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.

```json
  "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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/dist/background.js), this script manages API calls and storage.

```json
  "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.

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

```

### 6. Add Extension Icons (Optional)

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

```json
  "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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/dist/manifest.json):

```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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/manifest.json) to locate [`background.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/background.js) and [`index.html`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/manifest.json) configuration:

```bash

# 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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/background.js) file referenced in [`manifest.json`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/manifest.json) handles API requests and browser events:

```javascript
// 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();
}

```

### Popup Script Interaction

The [`index.html`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/index.html) popup communicates with the background service worker to display data:

```javascript
// 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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/manifest.json) | Core configuration declaring permissions and entry points | [`5-browser-extension/start/dist/manifest.json`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/dist/manifest.json) |
| [`background.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/background.js) | Service worker handling background tasks and API calls | [`5-browser-extension/start/dist/background.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/dist/background.js) |
| [`index.html`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/index.html) | Popup interface displayed when clicking the extension icon | [`5-browser-extension/start/dist/index.html`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/dist/index.html) |
| [`index.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/index.js) | Source file containing popup logic, bundled into [`main.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/main.js) | [`5-browser-extension/start/src/index.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/src/index.js) |
| [`package.json`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/package.json) | NPM configuration with build scripts and dependencies | [`5-browser-extension/start/package.json`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/5-browser-extension/start/package.json) |
| [`README.md`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/README.md) | Curriculum documentation for the browser extension lesson | [`5-browser-extension/README.md`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/index.html) and [`background.js`](https://github.com/microsoft/Web-Dev-For-Beginners/blob/main/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.