DEV Community

Cover image for How to build a Chrome Extension

Posted on • Updated on


How to build a Chrome Extension

Chrome Extension Manifest Version 3 is out now!

Go check out our CHROME EXTENSION V3 course for easy to follow video lessons.

If you sign up for our newsletter, you can get 20% off the purchase price!

There are 5 parts to a Chrome extension

  1. the manifest file
  2. the background script
  3. the foreground script
  4. the popup page
  5. the options page

. . .


Everything begins with the 'manifest.json' file.

How, where, and when our extension interacts with the user's browser, is all contained within the manifest.

The manifest establishes the name, version, and description of our chrome extension as well as the background script, popup and options pages.

It also establishes where we can inject foreground scripts (more on that later...).

    "name": "obj ext",
    "description": "my ext",
    "version": "0.1.0",
    "manifest_version": 2,
    "icons": {
        "16": "./obj-16x16.png",
        "32": "./obj-32x32.png",
        "48": "./obj-48x48.png",
        "128": "./obj-128x128.png"
    "background": {
        "scripts": ["./background.js"]
    "options_page": "./options.html",
    "browser_action": {
        "default_popup": "popup.html"
    "permissions": [
Enter fullscreen mode Exit fullscreen mode



The background script ('background.js') is a JavaScript script that runs once our extension either gets installed or the user refreshes the extension manually.

The background script doesn't actually have access to any of the webpages your user is viewing, so your background script can't manipulate the DOM.

So how do we get our chrome extension to do stuff on the user's webpage then?

That's where the foreground script comes in.

Our background script has the ability to inject foreground scripts, as well as CSS if you want, into the page.

This is how we can manipulate the DOM of a webpage with a Chrome Extension.

How do we inject our foreground script into the foreground?

In the background.js script...

let active_tab_id = 0;

chrome.tabs.onActivated.addListener(tab => {
    chrome.tabs.get(tab.tabId, current_tab_info => {
        active_tab_id = tab.tabId;

        if (/^https:\/\/www\.google/.test(current_tab_info.url)) {
            chrome.tabs.insertCSS(null, { file: './mystyles.css' });
            chrome.tabs.executeScript(null, { file: './foreground.js' }, () => console.log('i injected'))
Enter fullscreen mode Exit fullscreen mode

...where we have a listener watching what we do with our tabs.
If the current tab we're on is the Google homepage, we inject our script into that tab.

The 'null' indicates the current tab we're viewing.
From there, our foreground.js script acts like any other script influencing an index.html page.
We have access to the window and document(DOM).
We can make the Google homepage's logo spin if we wanted to.


In the 'foreground.js' we write...

Enter fullscreen mode Exit fullscreen mode the 'mystyles.css' we write...

.spinspinspin {
    animation-name: spin;
    animation-duration: 1.0s;
    animation-iteration-count: infinite;

@keyframes spin {
    0% {
        transform: rotate(0deg);
    100% {
        transform: rotate(1440deg);
Enter fullscreen mode Exit fullscreen mode

...and just like that, when we navigate to the Google homepage, our foreground script injects and that logo will spin.


The 'popup.html' page is optional.

The popup page is what shows when the user clicks on our extension icon in the top right.
It's an html page with a script attached if you want.

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <h1>I'm the popup</h1>
Enter fullscreen mode Exit fullscreen mode



The 'options.html' page is just like the popup page.

It's what the user sees when they navigate to their extensions tab and click for the options.
It's also an html page with a script attached if you want.

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <h1>I'm the options</h1>
Enter fullscreen mode Exit fullscreen mode

. . .

So it's this relationship between the background and foreground--just like a front-end and back-end--that ties a Google Chrome Extension together.
If you want to check out a more in-depth guide, including how the foreground communicates with the background as well as state management in a Chrome Extension, check out my full video tutorial on YouTube, An Object Is A.

How To Build A Chrome Extension (2020 Web Development)

. . .

Ready to tackle React Chrome Extensions?

Check it out here:

Top comments (6)

hugekontrast profile image
Ashish Khare😎

Really helpful guide! Loved it. Thanks for sharing and keep stuff like this coming!

harlo11 profile image

Excellent! Straight forward explaination for each part! Thanks for the explaination 👍

sabarishcodes profile image
Sabarish Rajamohan

Good guide for Extension Development! Thanks man

silentkernel profile image
Ludovic Frank

Really interesting, thank you

lalanachami profile image
Lalana Chamika

Good stuff 🙌🏼

anirudhrowjee profile image
Anirudh Rowjee

This is extremely simple and well-written. I learned a lot!


11 Tips That Make You a Better Typescript Programmer

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields


Read the whole post now!