How to build advanced Chrome Extensions with React

Jesse Korzan
3 min readMar 4, 2020

--

New Starter Kit! Manifest v3, React 18
https://github.com/jessekorzan/react-chrome-extension-manifest-v3
UPDATED — Nov. 2022

Some tips and boilerplate code to save you time (React ^16)

This post assumes you are familiar with Create React App (CRA) and building a Chrome Extension.

Spoiler alert… https://github.com/jessekorzan/react-chrome-extension

I rely on Chrome Extensions. A handful I almost couldn’t live without for work stuff. A couple are even ones I built myself. Even at my meagre understanding of Javascript, Chrome Extensions are easy to get started with.

In other areas of my design work, sometimes I need (want?) robust, higher-fidelity prototypes. React has been handy in this regard. Or more so, Create React App (CRA). Which, again, is easy for someone of crude js ability like myself.

Long story short, I wanted to put these two together.

At first, it was easy enough. Moving past a basic “default_popup” Extension and into something 100% customizable was harder. And where it got hard was more about the build tools than working on the design.

Using React to build an “advanced” Chrome Extension has a couple minor speed bumps to smooth out. Specifically, the compiled React js files need to be injected into the DOM by the Chrome Extension background script.

For those not familiar… the /build folder of the compiled React app is the Chrome Extension (this is what you load into Chrome).

Due to the way React does its build process, the final javascript is split into multiple files and given unique random names. Every single time you do a build, you have to cut and paste those file names into your Chrome background script. PITA, for sure, especially if you’re like me and need 100 tries before the bug is gone.

Note… the background script (often called background.js) is the process that runs when an Extension starts up.

Solved

See the code… https://github.com/jessekorzan/react-chrome-extension

To re-iterate, I just want to hit ‘yarn build’ and have my extension code *work* without any extra steps. Or hacking CRA.

What worked for me was leveraging CRA’s asset-manifest.json file. It lists all the required filenames every build (you can look for it in any CRA /build folder). It’s easy to grab those filenames in the background script so the React code can be injected into the active webpage.

There are alternatives that you can Google. These include ejecting CRA to config webpack or running a script to rename and move files. Things like this aren’t in my comfort zone and a struggle to maintain.

Other bits in the boilerplate:

1. Simple technique to inject a DOM element to house the React app (“the extension”)

2. Option to use Shadow Dom to encapsulate your styles and avoid CSS collusion issues

3. Example of passing data between the React app and Chrome API

More details in the repo. Hopefully someone finds it useful :)

Repo… https://github.com/jessekorzan/react-chrome-extension

--

--