Chrome extensions for dummies
by Jef Vlamings
I only recently started programming after following courses on Codecademy and now I’m already building full-blown Chrome extensions. The first browser extension I made is “Loop” a YouTube video playlist to cue your favorite YouTube videos and play them like you would on your iPod. It has a simple and easy to use UI that popups up once you click a button in Chrome. To learn how I developed this in just two weeks, keep on reading!
Background information
Before you get started you should know that basic Javascript and HTML skills are required. If you need to refresh these, I strongly advise you to go to codeyear.com and take some courses.
Documentation
Once you got a hold on Javascript and HTML/DOM you should definitely pin the following webpages to your bookmarks because you’ll be visiting them a lot.
- Google Chrome Extensions documentation
- Stack Overflow – [google-chrome-extensions]
- Google Groups – Chrome extensions
I found myself mostly looking for answers on Stack Overflow because I felt like Google was skipping some not so obvious steps in their official documentation.
Types of extensions
There are 4 different kinds of user interfaces a Chrome extension can have. The official documentation is not so clear about all the options you have. But these 4 appearances are the ones you’re most likely to use.

Different UI's for Chrome extensions
- Browser Actions: add an icon next to your address bar (i.e. to show a popup)
- Page Actions: show a little icon in the address bar
- Desktop notifications: show notifications on your desktop
- Omnibox: add functionality to your address bar with predefined keywords
In this tutorial we will focus more on browser actions. The Chrome extension I built is a typical example of a browser action with a popup window. If you want to use one of the 4 appearances you’ll have to specify it in something called the “manifest file”.
Getting started
To build your very first Chrome extension, create a folder on your computer and call it something like “my first extension”. This folder will be used to store all the files necessary for your extension. The first file you need to create is the manifest file.
Manifest file
The manifest file contains all the information Chrome needs to understand how your extension should work. I’ll give you a quick overview of all the elements a proper manifest file needs. First of all, open a decent text editor (I like to use Sublime Text 2 or Textwrangler) and copy-paste these lines of code.
{
"name": "The name of your extension",
"description": "Explain what your extension does",
"version": "1",
"permissions": ["tabs", "http://*/*", "background"],
"background_page": "background.html",
"content_scripts": [{"matches": ["http://*/*"],"js": ["inject.js"]}],
"browser_action": {"default_icon": "16x16.png","popup": "popup.html"}
}
Now save this file as “manifest.json” in your extension folder.
Tip: notice how every rule is ended with a comma except the last one! JSON objects aren’t allowed to have a trailing comma.
- permissions: You need to set permissions if you want to use some of the API functionality of Chrome extensions.
- tabs: if you want to access tabs or detect when something changes in a tab.
- url: determine which webpages you want your extension to work with (use http://*/* for all websites).
- background: if you want to use a background page (clarified further down this page).
- background_page: specify the file that will serve as your background page.
- content_scripts
- matches: specify for which webpages the content script should be injected.
- js: specify the file that will serve as your content script.
- browser_action
- default_icon: specify where the icon for your extension is located (must be 16px wide and 16px high) in your extension folder.
- popup: specify the file that will serve as your popup page.
As you can see quite a lot of files are necessary to build a simple extension. Anyway let’s start to make a “Hello World!”-application.
Popup.html
Most Chrome extensions use a popup window that shows up if you click on an extension icon. This popup browser action, as Google likes to call it, is particularly useful if you want to show information to your users without interrupting the browsing experience. There are a lot of cases where a popup is much more efficient than opening a new webpage for instance.
To show “Hello World!” to your users, create a new file called “popup.html” and add the following lines of code.
<html>
<head><title>Hello World!</title></head>
<body>
<p>Hello World!</p>
</body>
</html>
A popup is simply displaying a local HTML-file in a dedicated window. The good part is that you don’t have to worry about browser compatibility since your building this extension exclusively for Chrome. It’s the perfect playground to experiment with some of the recently supported HTML5 tags.
Hey presto! Your first extension!
Now you should have a folder on your computer with 2 files, i.e. “manifest.json” and “popup.html“. That’s all it takes to create a Chrome extension.
But since we also specified other files in our manifest file we must add those files to the folder as well. So before you can fire up your extension, create the next dummy files, which we’ll be needing for the rest of the tutorial. Don’t worry about the purpose of these files yet. It will all be explained further down this page.
- background.html: create an empty HTML-file with the appropriate tags
- inject.js: create an empty Javascript file
- 16×16.png: you need a 16 by 16px icon. (grab my icon over here, if you don’t want to be bothered with it)
Now let’s fire it up. Open your Chrome browser and go to the extensions page. Click on the wrench icon next to the address bar and choose Tools >> extensions. Make sure “developer mode” is ticked. Next, click on “Load unpacked extension” and choose your folder in the file dialog. Your extension should now be loaded in your Chrome browser. To confirm if everything went well, check if a new icon appeared next to the address bar.
If you click on it you should see something like this:

Extension Popup showing Hello World!
Congratulations! You’ve just build your first Chrome extension. From now on, we’ll dive deeper into the possibilities of extensions.
Execution environments
I think it’s about time to talk about background pages and content scripts. Background pages and content scripts are actually the same. They are both files where most of the coding happens. The main difference is that background pages and content scripts run in different execution environments. Background pages run in the extension environment and are hidden from the user, while content scrips run in the webpage environment and can affect the web page you’re visiting.
Just like me, you’re probably wondering why Google made it so complicated. It actually has a very important purpose, i.e. if your extension runs in a different environment you’ll never have to worry about your code interfering with the one of the webpages. This means you can use the same variable, function or object names as the website with absolutely no interference.
In my extension (Loop), I used three extra files of which I’ll be discussing two:
- Background.html. This is my background page which holds most of the code. All information I gather is controlled in this file.
- Inject.js. This is a content script I load in every YouTube page. It tells me all about the video I’m watching.
Background pages

Background pages vs browser actions
Background pages are scripts that run in the background. The benefits of background pages is that they are able to communicate with every tab and every extension file in you browser. It doesn’t matter how many tabs or windows you’ve opened, it can easily detect changes being made. On top of that background pages can also communicate with browser actions and content scripts. So they serve as the ideal negotiator between your popup, your content script and the webpages that are being viewed.
<html>
<script>
console.log("Hello World!");
<script>
</html>
A background page is nothing more than Javascript code being wrapped in an HTML-file. Make sure you use it wisely because background pages are always open. This means that from the moment you start Chrome, your background pages are being loaded. If they demand a lot of computing power or network bandwidth, you’re browsing experience could be harmed.
Debugging
Keep in mind that background pages run in the background (strangely enough). If you want to see error messages or console logs you won’t find it in the standard debugging console of your browser because they’re are meant for webpages. Background pages run in the extension environment and thus have a dedicated debugging console.

Debugging console for background.html
To activate this console, go to the extensions page and click on “background.html” listed in your extension.
Tip. type “chrome://settings/extensions” in your address bar or right-click your extension icon and click “manage extensions..”.
Content scripts
In most cases you’ll want to read the DOM of the visited webpages. Since extensions run in a different execution environment it is impossible for background pages or browser actions to read DOM-elements of the webpages you’re visiting. Google came up with something clever called “content scipts”. Content scripts are injected in the current webpage as if they were supplied by the original website.

Content scripts have the benefit of communicating with background pages while maintaining the ability to read the DOM of the webpages you’re visiting. The downside of using content scripts is that you can’t directly call Chrome API functions from within the content script because they’re separated from the extension environment.
So how can you pass information from a content script to a background page and vice versa if they run in different execution environments? Luckily there are ways to work around this with something called “message passing”.
Message passing
Through message passing you’re able to send and receive information between content scripts and background pages. Message passing is done like this:
To send a request add this piece of code.
chrome.extension.sendRequest({
"greeting": "hello",
"var1": "variable 1", //string
"var2": true //boolean
});
The first variable could serve as a recognition phrase. That’s how I tend to use it. Make sure you don’t add a trailing comma to the array or your code will fail.
On the receiving end add something like this:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.greeting == "hello"){
var1 = request.var1; // Set variable 1
var2 = request.var2; // Set variable 2
}
else{
sendResponse({}); // Stop
}
});
Although this piece of code listens to all the requests that are being sent from other files in the extension, it will only store information if the variable of greeting has the string “hello” attached to it. It’s a simple but effective method to distinguish between different requests.
It doesn’t matter if you’re in a content script or in a background page, the way messages are being passed remains the same. So you could put the code for the reception of a request in any of the files.
Conclusion
I tried to give a brief overview of how Chrome extensions work and how they are being built. I hope this short introduction will set you off to start and build something beautiful. To conclude I would like to give some extra advice to beginners.
Please, take your time to build your first extension. You will get frustrated at one point because you’ll find yourself in situations where you’re code isn’t running like it should or the documentation is inadequate and you can’t reproduce another ones output. Just keep calm and keep trying. If nothing seems to work, just try trial-and-error and you’ll stumble upon some answers eventually. Also, try to understand what you’re doing, it will help you in the long run and you’ll benefit from it later on. After all making your first extension is probably more about learning than about delivering a complete product.
If you want to snoop around in the source code of my first extension, feel free to go and check it out on GitHub! You can find the full code base on my GitHub page.
If you still have some questions left, feel free to ask questions in the comment section below or check out one of the suggested links. Good luck with your first Chrome extension!

Thank you so much, Jef. It worked like a charm.
I’m glad you liked it!
Love it! Glad to see a fellow newbie creating!
awesomeness. I just created a simple extension! Thanks.
Great article, Jef. I think you should add that you can request permission for cross domain XMLHTTPRequests on a per domain basis. (The user accepts / denies them when they install your extension).
I was wondering if you could either make this extension or give me heads up on how to go about making it. Instead of the Google+ button, I would like to make a Quagmire that says Giggity.
I guess you could inject a content script in all websites you visit which replaces the standard Google+ button with you own customized button.
You’ll need to find the specific class or id a google+ button uses and use some JS magic to replaced it with something else like:
document.getElementByID(“…”).innerHTML =
Nice article. Have you tried building a safari extension? If so are you thinking of doing a similar tutorial for it?
Thanks Christian. I never tried to build a Safari extension and I don’t have any future plans to do so. I’ve got some other exciting stuff in the pipeline. Follow me on twitter to stay tuned. @jefvlamings
Hi,I would like to know why my Icon isn’t appearing in the chrome://settings/extensions page. I included an icon48 on my img folder and also on manifest.json
Hey, I might be missing something obvious, but do you have any advice on how to manipulate the DOM in a tab by pressing buttons from the popup view?
Thanks
You’re going to want to write one or more “content scripts,” which are scripts that are injected into every page in a tab when the page is loaded. Package these scripts as part of your extension and declare them in the manifest.
Then you’ll want to use messages (another Chrome extension facility) to communicate between the extension and the scripts injected into each page.
Very well done. That second diagram showing the different display types for extensions is particularly helpful. I just made my first Chrome extension and was thinking of putting together a similar blog – but yours does a much better job of explaining things than I would have.
Maybe..I’ll write something up explaining the details of localStorage and page/tab update events. My extension involves quite a bit of page action->content script message passing, so maybe I can expound on that concept.
Either way..you’ve gained a reader. Thanks.
Great Tutorail..!!
Certainly u have taken lot pain to develope it..
Appreciated .!!
Thanks
Sandeep
India
At this time I am going away to do my breakfast, after having my
breakfast coming over again to read additional news.
I am getting all frustrated and mad because I copy / paste exactly what it is here. I delete all content in both js and leave only what is here, and always the same error:
“Port error: Could not establish connection. Receiving end does not exist. ”
What the hell?? Can someone help me?
You should be a part of a contest for one of the finest blogs online.
I am going to highly recommend this site!
Hi there I am so thrilled I found your blog,
I really found you by error, while I was looking on Digg for
something else, Nonetheless I am here now and would just like to say cheers
for a remarkable post and a all round thrilling blog (I also love
the theme/design), I don’t have time to read through it all at the minute but I have bookmarked it and also added your RSS feeds, so when I have time I will be back to read much more, Please do keep up the excellent job.
Hi there! I could have sworn I’ve been to this website before but after checking through some of the post I realized it’s new to me.
Nonetheless, I’m definitely happy I found it and I’ll be book-marking and checking
back often!
Howdy! I simply would like to give you a huge thumbs up
for the great information you’ve got right here on this post. I am returning to your web site for more soon.
I tried installing the loop extension but I requires “manifest_version” 2, (Chrome stable version v23)
I changed this but then Chrome warns me that the background.html requires “manifest_version” 1.
Any chances of updating the loop and this example ?
Thanks,
Emile
Could you please share source code of message passing, its been a nightmare.
Will be very helpful, if you share by one of your extension loop for youtube videos.
Thanks
Sankar
I want to develop an browser extension (which probably run across all types of browser )
1) Which can record user’s h/w level interactions (like mouse scroll, mouse click, k/b events) on each visited page,
2) stores it in local database(like page URL, type of such events, and number(frequency) of such events
Please give me guidance how to start !
This is an outstanding explanation and overview of chrome extensions.
Thank you for a wonderful worded article.
Я в ахуе, господа присяжные заседатели. Пойду подрочу.
The title is freakin arrogant for somebody who started coding with codecademy
I simply want to mention I am just very new to blogs and seriously savored your web blog. Most likely I’m likely to bookmark your blog post . You surely come with exceptional stories. Thank you for sharing with us your webpage.
Only wanna input on few general things, The website design is perfect, the written content is very great
.
Wohh precisely what I was searching for, appreciate it for putting up. “Be nice to everyone on your way to the top because you pass them all on the way down.” by Fred Hufnagel, Sr..
Hello There. I discovered your weblog the use of msn. That is an extremely well written article. I’ll be sure to bookmark it and come back to read extra of your helpful information. Thank you for the post. I’ll certainly return.
I have recently started a website, the info you provide on this site has helped me greatly. Thanks for all of your time & work. “It is no use saying, ‘We are doing our best.’ You have got to succeed in doing what is necessary.” by Sir Winston Churchill.
Simply want to say your article is as surprising. The clearness on your post is simply great and that i could suppose you are knowledgeable on this subject. Well together with your permission let me to take hold of your RSS feed to keep updated with forthcoming post. Thanks a million and please keep up the gratifying work.
After study just a few of the weblog posts on your website now, and I actually like your way of blogging. I bookmarked it to my bookmark website record and will likely be checking back soon. Pls try my web page as effectively and let me know what you think.
Thankyou for this terrific post, I am glad I discovered this internet site on yahoo.
Great post, you have pointed out some great details , I likewise conceive this s a very wonderful website.
Hi there! Do you know if they make any plugins to protect against hackers? I’m kinda paranoid about losing everything I’ve worked hard on. Any recommendations?
Any time you notice irregular, unstraight stitches or perhaps even topics arriving drop, damaging to an artificial.
Outstanding post, I think website owners should larn a lot from this web site its real user pleasant. “Choose your pleasures for yourself, and do not let them be imposed upon you.” by Lord Chesterfield.
Merely wanna comment on few general things, The website style and design is perfect, the written content is really excellent. “Believe those who are seeking the truth. Doubt those who find it.” by Andre Gide.
If you want that your cherished replica hublot big bang with great care, then your search is over