Creating a Chrome Extension Without Much Effort

My baby Chrome extension
My baby Chrome extension

Honestly, I thought that Chrome extensions were more effort than they were worth to develop. I thought my extension would have to be useful for other people on the Chrome Web Store. Here’s how I was wrong.

Skip to “Making the Extension” if you just want the goods.

The Use Case

I work at The Zebra. It’s a neat place with smart software engineers collaborating on interesting problems.

Any place that has software engineers has people griping and sniping about their tools. We’re craftspeople and take pride in our efficiency.

At The Zebra, we have an expectation that developers will squash their commits before merging into master. This was not an issue back when we used GitHub for hosting our Git repos. GitHub had useful configuration that allowed admins to enforce squashed commits. All was right with the world. A few folks really wanted us to delete our source branches. 🤷

We found no such option when we moved over to GitLab. In fact, our developers found an old GitLab issue asking for this functionality (2 years old at the time of writing).

We’ve lived with it for a little over half a year before I decided to look into whether a Chrome extension could solve the problem for us. At least, it could solve it for me.

The Setup

At the core of our issue was that the GitLab Merge Request UI had a little checkbox that controlled squashing commits on merge. We simply needed that box to be checked as the Merge Request screen loaded, effectively protecting our squash commit culture by default. Bonus if developers could uncheck the box in case they really wanted to include their discrete commits in master.

I didn’t want to read a single bit of Chrome Extension documentation. I actively refused to. It was nearing midnight and I gave myself a 30 minute time limit to make things interesting.

So I set off to Google how to do this. I found a great article by thoughtbot.. but it was over a few screens worth of scrolling so I decided to just skim the code to see if I could get the gist. I had Netflix to watch, ice cream to eat.

What’s to stop you from doing the same thing? Nothing really, go ahead.

Making the Extension

I needed exactly two files for my purposes:

2|- manifest.json (small config for extension)
3`- content.js (the actual browser code)

The manifest.json file is just that; a manifest. This is how Chrome will understand your extension and when to apply it.


2 "manifest_version": 2,
3 "name": "GitLab Squash Default",
4 "version": "0.1",
5 "content_scripts": [
6 {
7 "matches": ["*/merge_requests/*"],
8 "js": ["content.js"]
9 }
10 ]

Here’s a rundown of the most important values.

  • name: How you’ll recognize your extension when applying it
  • manifest_version: This should be set to 2 as the earlier version isn’t supported. Don’t ask me why; I skimmed, remember?
  • content_scripts: You probably want your extension to run against a single URL or a URL pattern. Set that here. It’s nice to know that you can use wildcards. My extension is only applied to URLs that begin with and must then include /merge_requests/ in the middle of the path somewhere. I also specify what file runs against those matching URLs.


1window.addEventListener('load', () => {
2 checkSquash = setInterval(() => {
3 const checkbox = document.querySelector("input[name='squash']")
4 if (checkbox) {
5 checkbox.checked = true;
6 clearInterval(checkSquash);
7 }
8 }, 250);

And that’s all the JS that I needed to make the functionality. This little code snippet would fire whenever the URL matched GitLab’s Merge Request screen and the desired checkbox would be checked upon its availability in the DOM. 🎉 🎉 🎉

Enabling the Extension

With those two files written, follow these steps to enable it for your use:

  • Go to chrome://extensions/ in the Chrome.
  • Enable Developer mode. This is a toggle on the top right of the page as of Chrome 80.
  • Click Load unpacked and select the directory your files are in.
  • Enable the extension, the name will match what’s in manifest.json.
  • Test it by going to your specified URLs!

If you don’t see that the extension is working correctly, check for errors on the extensions page. You can also reload the extension after making changes.

That’s it, hope that helps you. Feel free to check out my extension if you like. Yep, I’m hosting my extension for GitLab on GitHub.

I’d appreciate any comments if you found this useful or entertaining. I’m looking to start writing more and could use the encouragement. Also, we’re always hiring at The Zebra.