How to Build a Chrome Extension and Publish It to the Chrome Web Store (2026 Guide)

AppBooster Team · · 9 min read
Developer coding on laptop with browser open

Why Build a Chrome Extension?

With over 3.8 billion Chrome users worldwide, Chrome extensions offer developers direct access to a massive audience. Whether you want to build a productivity tool, automate workflows, or create a SaaS product — extensions are one of the fastest ways to ship software that people use daily.

The barrier to entry is low: if you know HTML, CSS, and JavaScript, you already have everything you need.


Part 1: Setting Up Your Development Environment

Prerequisites

  • Google Chrome (latest stable version)
  • Code editor (VS Code recommended)
  • Basic knowledge of HTML, CSS, and JavaScript

No special SDKs, compilers, or build tools required for simple extensions.

Project Structure

Create a new folder for your extension. A minimal Chrome extension needs just one file — manifest.json — but most real extensions follow this structure:

my-extension/
├── manifest.json        # Required: extension configuration
├── service-worker.js    # Background logic (event-driven)
├── content.js           # Injected into web pages
├── popup.html           # Toolbar popup UI
├── popup.js             # Popup logic
├── popup.css            # Popup styles
├── options.html         # Settings page (optional)
└── icons/
    ├── icon-16.png
    ├── icon-48.png
    └── icon-128.png

Part 2: Writing Your First Extension

Step 1: Create the Manifest

The manifest.json file is your extension’s blueprint. Every extension must use Manifest V3 (V2 is fully deprecated as of 2024).

{
  "manifest_version": 3,
  "name": "My First Extension",
  "version": "1.0.0",
  "description": "A simple extension that greets users",
  "permissions": ["activeTab", "storage"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icons/icon-16.png",
      "48": "icons/icon-48.png",
      "128": "icons/icon-128.png"
    }
  },
  "background": {
    "service_worker": "service-worker.js"
  },
  "content_scripts": [
    {
      "matches": ["https://*/*"],
      "js": ["content.js"]
    }
  ]
}

Key fields explained:

  • manifest_version: Must be 3 — non-negotiable
  • permissions: Declare only what you need (reviewed by Google)
  • host_permissions: Separate field for website access patterns
  • action: Controls the toolbar icon and popup
  • background.service_worker: Replaces the old background page model

Step 2: Build the Popup UI

Create popup.html — the interface users see when clicking your extension icon:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="popup.css">
</head>
<body>
  <div class="container">
    <h1>Hello, Extension!</h1>
    <p id="status">Click the button to get started.</p>
    <button id="action-btn">Do Something</button>
  </div>
  <script src="popup.js"></script>
</body>
</html>
/* popup.css */
body {
  width: 320px;
  padding: 16px;
  font-family: system-ui, sans-serif;
}
.container { text-align: center; }
button {
  background: #4285f4;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}
button:hover { background: #3367d6; }
// popup.js
document.getElementById('action-btn').addEventListener('click', async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
  chrome.tabs.sendMessage(tab.id, { action: 'greet' });
  document.getElementById('status').textContent = 'Message sent!';
});

Step 3: Add a Service Worker

The service worker handles background events. Unlike MV2 background pages, service workers are event-driven and terminate when idle:

// service-worker.js
chrome.runtime.onInstalled.addListener(() => {
  console.log('Extension installed successfully');
});

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'getData') {
    // Handle background tasks
    sendResponse({ data: 'Hello from service worker' });
  }
});

Important: Register all event listeners at the top level — not inside callbacks or promises.

Step 4: Create a Content Script

Content scripts run in the context of web pages and can manipulate the DOM:

// content.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'greet') {
    const banner = document.createElement('div');
    banner.textContent = '👋 Hello from My Extension!';
    banner.style.cssText = `
      position: fixed; top: 0; left: 0; right: 0;
      background: #4285f4; color: white;
      padding: 12px; text-align: center;
      z-index: 99999; font-family: system-ui;
    `;
    document.body.prepend(banner);
    setTimeout(() => banner.remove(), 3000);
  }
});

Part 3: Loading and Debugging Your Extension

Load Your Extension in Chrome

  1. Open chrome://extensions/ in your browser
  2. Enable Developer mode (toggle in top-right corner)
  3. Click “Load unpacked”
  4. Select your extension folder
  5. Your extension appears in the toolbar immediately

Debugging Techniques

ComponentHow to Debug
Service WorkerClick “service worker” link on the extension card
PopupRight-click extension icon → “Inspect popup”
Content ScriptOpen page DevTools → Console tab (select extension context)

Pro tips:

  • Changes to code require clicking the refresh icon on chrome://extensions/
  • Changes to manifest.json require removing and re-loading the extension
  • Use chrome.storage for persistent data — service worker variables are lost on termination
  • Check the Errors button on your extension card for crash reports

Part 4: Key APIs You Should Know

APIPurposePermission
chrome.storagePersist data locally or sync across devicesstorage
chrome.tabsQuery and manipulate browser tabstabs
chrome.alarmsSchedule recurring background tasksalarms
chrome.contextMenusAdd right-click menu itemscontextMenus
chrome.notificationsShow desktop notificationsnotifications
chrome.declarativeNetRequestBlock/modify network requestsdeclarativeNetRequest

Communication Between Components

Extensions use message passing to communicate between popup, service worker, and content scripts:

// Send message from popup to service worker
chrome.runtime.sendMessage({ action: 'fetchData' }, (response) => {
  console.log(response);
});

// Send message from service worker to content script
chrome.tabs.sendMessage(tabId, { action: 'updateUI' });

Part 5: Publishing to the Chrome Web Store

Once your extension is tested and ready, here’s how to get it in front of users.

Step 1: Register as a Developer

  1. Go to the Chrome Web Store Developer Dashboard
  2. Sign in with your Google account
  3. Pay the one-time $5 registration fee
  4. Enable 2-Step Verification on your Google account (mandatory)

Step 2: Prepare Your Assets

You’ll need these before submitting:

AssetRequirements
Extension icon128×128 PNG (96×96 visible area + 16px padding)
Screenshots1-5 images, 1280×800 pixels recommended
Short descriptionUp to 132 characters
Full descriptionUp to 16,000 characters — explain features and benefits
Privacy policy URLRequired if you handle any user data

Screenshot tips: Show your extension in real use. Highlight key features. Avoid generic mockups — reviewers want to see actual functionality.

Step 3: Package Your Extension

Create a .zip file of your extension folder (the folder containing manifest.json at the root):

cd my-extension
zip -r ../my-extension.zip . -x ".*" -x "__MACOSX"

Step 4: Submit for Review

  1. In the Developer Dashboard, click “New Item”
  2. Upload your .zip file
  3. Fill in the Store Listing tab:
    • Name, description, category, language
    • Upload icon and screenshots
  4. Complete the Privacy tab:
    • Declare data usage practices
    • Provide privacy policy URL if applicable
    • Justify every permission you declared
  5. Set Distribution options:
    • Public (visible to all) or Unlisted (accessible via direct link)
    • Geographic targeting (optional)
  6. Click “Submit for Review”

Step 5: Wait for Review

  • Typical timeline: 1-3 days for simple extensions, up to 7 days for complex ones
  • Manual review triggered by: Sensitive permissions, network request APIs, or policy flags
  • After approval: Your extension goes live immediately

Speed up approval:

  • Declare minimal permissions
  • Write clear permission justifications
  • Ensure your privacy policy matches actual behavior
  • Test thoroughly — crashes trigger rejection
  • Follow all Chrome Web Store policies

Part 6: After Publishing — What’s Next?

Monitor Performance

  • Track installs, uninstalls, and active users in the Developer Dashboard
  • Respond to user reviews promptly
  • Monitor crash reports and fix issues quickly

Update Your Extension

  1. Increment the version in manifest.json
  2. Upload a new .zip to the Developer Dashboard
  3. Updates go through review again (usually faster than initial submission)
  4. Chrome auto-updates extensions for users within a few hours of approval

Grow Your User Base

  • Optimize your store listing with relevant keywords
  • Encourage satisfied users to leave reviews
  • Create a landing page or documentation site
  • Engage with your user community
  • Use tools like ExtensionBooster to analyze and improve your store presence

Common Mistakes to Avoid

  1. Requesting excessive permissions — Only declare what you actually use. Broad permissions trigger longer reviews and scare users.
  2. Using remote code — Manifest V3 prohibits remotely-hosted JavaScript. All code must be bundled in your extension package.
  3. Ignoring service worker lifecycle — Don’t store state in variables; use chrome.storage. Service workers terminate when idle.
  4. Misleading store listing — Your description and screenshots must accurately represent functionality. Mismatches lead to rejection.
  5. Missing privacy policy — If your extension accesses any user data (even just the current tab URL), you need a privacy policy.

Helpful Resources


Conclusion

Building and publishing a Chrome extension is remarkably accessible. With just HTML, CSS, and JavaScript, you can create tools that reach billions of users through the Chrome Web Store. The key steps are straightforward: structure your project with Manifest V3, build your UI and logic, test locally with Developer mode, then submit through the Developer Dashboard with proper assets and documentation.

The $5 registration fee and a few days of review time are all that stand between your idea and a published extension. Start small, iterate based on user feedback, and grow from there.

Ready to build? Create your manifest.json and load it as an unpacked extension today. Your first Chrome extension is just a few files away.

Share this article

Build better extensions with free tools

Icon generator, MV3 converter, review exporter, and more — no signup needed.

Related Articles