What you need to know before you start building

A Chrome extension is a small program that adds a feature or changes how a webpage works in your browser. You write it using the same languages web designers use: HTML (the structure), CSS (the appearance), and JavaScript (the behavior). Chrome provides the tools to package your code and load it into your browser for testing.

You do not need to publish your extension to the Chrome Web Store to use it. You can build it, load it locally on your own computer, and run it only for yourself. This is how most people start — they solve a problem they have, test it thoroughly, and only then decide whether to share it publicly.

The barrier to entry is low if you already know how to write HTML, CSS, and JavaScript. If you do not, you will need to learn those languages first. There are free tutorials online (Mozilla Developer Network and freeCodeCamp are both solid starting points), and the learning curve is gentler than you might expect.

Key Takeaways

  • Chrome extensions use HTML, CSS, and JavaScript — the same languages that power websites — so you can reuse skills you may already have.
  • You can build and test an extension on your own computer without publishing it, which is the standard way to start.
  • Every extension needs a manifest file (manifest.json) that tells Chrome what the extension does and what permissions it needs.
  • Chrome's developer mode lets you load your extension folder directly into the browser, so you can test changes when ready without repackaging.
  • Permissions are the most important security decision you make — only request the permissions your extension actually needs to work.

The three files every extension needs

Every Chrome extension has at least three files: manifest.json, popup.html, and popup.js. The manifest is the instruction manual that tells Chrome what your extension is called, what it does, what permissions it needs, and which files to load. The HTML file is what the user sees when they click your extension icon. The JavaScript file is where the behavior lives — the code that actually does the work.

The manifest.json file is the most important. Here is what a minimal one looks like:

{ "manifest_version": 3, "name": "My First Extension", "version": "1.0", "description": "A straightforward extension that does one thing", "permissions": ["activeTab"], "action": { "default_popup": "popup.html", "default_title": "Click me" } }

The "manifest_version": 3 line is required — it tells Chrome you are using the current format. Older extensions used version 2, but Chrome stopped supporting those in 2023. The "permissions" array is where you list what your extension is allowed to do. "activeTab" means it can see and modify the webpage the user is currently viewing. If you do not need that, leave it out.

Setting up your folder and loading it into Chrome

Create a folder on your computer called something like "my-extension". Inside it, put your manifest.json, popup.html, and popup.js files. You can organize them however you want — some people put all three in the root folder, others create a "src" subfolder. Chrome does not care as long as the manifest.json is in the folder you point it to.

Open Chrome and go to chrome://extensions. In the top right corner, turn on Developer mode. A new button called "Load unpacked" will appear. Click it, navigate to your extension folder, and select it. Chrome will load your extension when ready, and you will see it in the list with an icon.

Every time you change your code, refresh the extension. Click the refresh icon next to your extension's name in the chrome://extensions page. Your changes will take effect in the browser right away. This is much faster than packaging and reinstalling.

Understanding permissions and why they matter

Permissions are the security boundary of your extension. They control what data your extension can access and what actions it can take. The most powerful permissions are the ones that let you read or modify webpage content, access your browsing history, or read your cookies.

Only request the permissions you actually need. If your extension only changes the color of links on a page, you do not need permission to read your browsing history. If it only works on one website, use the "host_permissions" field to limit it to that domain instead of asking for permission on all websites. Users see the permissions your extension requests, and overly broad permissions make people distrust your extension — even if you have no intention of misusing them.

Common permissions include:

  • activeTab — read and modify the current webpage
  • scripting — inject JavaScript code into webpages
  • storage — save data locally on the user's computer
  • host_permissions — limit access to specific websites (for example, "https://example.com/*")

A working example: a straightforward text highlighter

Here is a complete, minimal extension that highlights all instances of a word on the current page. Create these three files in your extension folder.

manifest.json:

{ "manifest_version": 3, "name": "Word Highlighter", "version": "1.0", "description": "Highlight a word on the page", "permissions": ["activeTab", "scripting"], "action": { "default_popup": "popup.html" } }

popup.html:

<!DOCTYPE html> <html> <head> <style> body { font-family: Arial; padding: 10px; width: 200px; } input { width: 100%; padding: 5px; } button { width: 100%; padding: 5px; margin-top: 5px; } </style> </head> <body> <input type="text" id="word" placeholder="Enter word to highlight"> <button id="highlight">Highlight</button> <script src="popup.js"></script> </body> </html>

popup.js:

document.getElementById("highlight").addEventListener("click", async () => { const word = document.getElementById("word").value; const [tab] = await chrome.tabs.query({active: true, currentWindow: true}); chrome.scripting.executeScript({ target: {tabId: tab.id}, function: highlightWord, args: [word] }); }); function highlightWord(word) { const regex = new RegExp(word, "gi"); document.body.innerHTML = document.body.innerHTML.replace(regex, match => `<mark>${match}</mark>`); }

Load this into Chrome using the steps above. Click the extension icon, type a word, and click Highlight. Every instance of that word on the page will be wrapped in a yellow highlight. This example shows how the popup talks to the webpage, how permissions work, and how to pass data between files.

Testing and debugging your extension

Chrome's developer tools work on extensions just like they work on websites. Right-click your extension icon and select "Inspect popup". A developer console will open showing any errors in your code. If something is not working, check the console first — JavaScript errors will be listed there with line numbers.

If your extension modifies webpages, open the developer tools on the webpage itself (press F12) and look at the Elements tab to see what your code changed. The Console tab will show any errors that happened when your extension ran.

Test on multiple websites and in multiple scenarios. If your extension is supposed to work only on certain sites, test that it does not break other sites. If it reads user input, test what happens when the input is empty or contains unusual characters. The more thoroughly you test before sharing, the fewer problems users will encounter.

Publishing to the Chrome Web Store (optional)

If you want other people to use your extension, you can publish it to the Chrome Web Store. You will need a Google account and a one-time developer fee (currently $5). You upload your extension as a .zip file, write a description and take screenshots, and Google reviews it to make sure it does not violate their policies.

The review process usually takes a few days. Google checks that your extension does what it claims to do, that it does not contain malware, and that it does not request permissions it does not actually use. If your extension passes, it goes live and anyone can find it by searching the Chrome Web Store.

You do not have to publish to share your extension. You can send the folder to friends, or post it on GitHub and let people load it locally using the steps above. Local loading is common during development and for extensions you only want a few people to use.

Frequently Asked Questions

Can I use a library like jQuery or React in my extension?

Yes, but you have to include the library files in your extension folder and reference them in your HTML. You cannot load libraries from a CDN (a website that hosts them) because of security restrictions. read the library, put it in your folder, and link to it like you would any local file.

What happens if I request a permission I do not actually use?

Users will see that permission in the install dialog and may distrust your extension. Chrome also reviews permissions during the Web Store review process and may reject your extension if the permissions do not match what the extension does. Only request what you need.

Can I modify extensions that other people wrote?

Yes, for your own use. read the extension's code (if it is open source), modify it, and load it locally. You cannot republish someone else's extension as your own, but you can fork it and make your own version if the original license allows it. Check the license before you modify.

How do I update my extension after I publish it?

Upload a new version to the Chrome Web Store with an updated version number in your manifest.json. Chrome will automatically push the update to users within a few hours. You do not have to do anything else — users do not have to reinstall or manually update.

What is the difference between a popup and a background script?

A popup is the small window that opens when you click your extension icon. A background script runs in the background all the time, even when the popup is closed. Use a popup for straightforward actions the user triggers manually. Use a background script if your extension needs to monitor tabs, respond to events, or run code even when the user is not interacting with it.