React starter kit for Chrome Extensions with Live Reloading š¤
May 7, 2019
Software is eating the world. And JavaScript is eating software. Chrome extensions are not an exception here. They are also built using JavaScript. A few days ago, I got an opportunity to work on a small side project which needed a chrome extension. Since I am new to ReactJs and want to tame it, so I decided to build the desired extension with it. Before I narrate the whole story, letās take a gander on how one develops a chrome extension.
Chrome extension overview
Every chrome extension starts with a manifest.json file which provides an overview of the permissions, background scripts, content scripts, popups and many other things used by the extension. Hereās a sample manifest file.
{ "name": "Getting Started Example", "version": "1.0", "description": "Build an Extension!", "permissions": ["storage"], "background": { "scripts": ["background.js"], "persistent": false }, "page_action": { "default_popup": "popup.html", "default_icon": { "16": "images/get_started16.png", "32": "images/get_started32.png", "48": "images/get_started48.png", "128": "images/get_started128.png" } }, "manifest_version": 2}Folder/bundle containing a manifest file, scripts, and other assets, is loaded into chrome from chrome://extensions/ page. Chrome reads the manifest file and installs the extension. If any change is made in script or any other file, we reload the extension to install the latest change.
Hereās a link to the official documentation which elborates chrome extensions and their installations.
After getting familiar with the basics of extension development, I put on my developer hat š¤ and started building an extension with create-react-app. Here are the steps I followed:
- Created a react app by runnning
create-react-app hello-extensions- Replaced
manifest.jsonfile with below content.
{ "name": "Hello Extension", "description": "My first chrome extension", "version": "1.0", "manifest_version": 2, "browser_action": { "default_popup": "index.html" }, "content_security_policy": "script-src 'self' 'sha256-5As4+...'; object-src 'self'"}- Build the app using
npm run build- Loaded the build in chrome.
ā¦and it worked. Yay!!

My āHello Worldā moment with extension made me happy but my happiness didnāt last for long when I decided to change the background color. I found out that I have to build and reload the extension again š©.
Build changes š¤
Running an app(created by create-react-app) in development mode with npm run start doesnāt write files to the disk. I needed files to be present on the disk so that they can be loaded in chrome. As we know, the create-react-app utility uses webpack under the hood with a predefined configuration. And to customize that predefined config we must eject it first. So I ejected the config with the command npm run eject. It generated some config files and scripts.

After ejecting the configuration, I needed to find a way to write files to disk in development mode. I ran to the webpack dev server api document for help and found an option writeToDisk. As its name suggests, setting writeToDisk true will write files to disk. So I set it true in the dev server config. It helped but it took a toll on the dev server. Dev server became sluggish. Its sluggishness convinced me to look for a better alternative.
I thought for a while and realized that I didnāt need a dev server. I needed a āwatch serverā š
. A server to watch files and copy themāwith the latest changesāto build directory on the change event. I leveraged webpack.watch api and ended up with the watch script below.
// some neccessary setup code.........
// Webpack watchwebpack(config).watch({}, (err, stats) => { if (err) { console.error(err); } else { copyPublicFolder(); } console.error( stats.toString({ chunks: false, colors: true }) );});
function copyPublicFolder() { fs.copySync(paths.appPublic, paths.appBuild, { dereference: true, filter: file => file !== paths.appHtml });}Reload changes š
After dealing with the build barrier, the next challenge was to automatically reload the extension. I found a supercool webpack plugin webpack-chrome-extension-reloader which reloads chrome extensions out of the box. A million thanks to Rubens for writing it. A sneak peek of config with the plugin.
// Other configuration............
plugins: [ // Other plugins ... ... ... // Chrome extension hot reloading. isEnvDevelopment && new ChromeExtensionReloader({ reloadPage: true // Force the reload of the page also entries: { // The entries used for the content/background scripts contentScript: 'content-script', background: 'app' // *REQUIRED } }) ].filter(Boolean),Illustration of the starter kit with live reloading.

Hereās the link to complete package/starter kit. I hope it will be helpful. If you have any idea/suggestion to make it better, please do share. Thanks šš». Happy Coding!
Hi, I am Hitesh.
I build things and ship some of them.