Creating a Chrome Extension with React and Vite (Boilerplate provided)

Creating a Chrome Extension shouldn’t be this complicated

Chris Oh
5 min readJul 7, 2024

TLDR: Boilerplate here https://github.com/5tigerjelly/chrome-extension-react-template

In this post, I’ll share my experience creating a Chrome extension, from using vanilla HTML, JS, and CSS to eventually migrating to React and using Vite for compilation. This journey was filled with challenges, lessons learned, and eventually a solution that I hope will help others in similar situations.

Photo by Orissa Humes on Unsplash

Getting Started with Vanilla HTML, JS, and CSS

When I first started, I followed the official Google documentation, which provided examples in vanilla HTML, JS, and CSS. This approach worked well for getting basic functionalities up and running. The documentation was clear and helped me understand the basics of Chrome extensions. I was able to create a simple extension that performed the tasks I wanted. However, as I delved deeper into more advanced features, I realized that working with vanilla HTML, JS, and CSS had its limitations, especially in terms of maintainability and scalability.

One significant challenge was managing the manifest file, especially with the recent migration from manifest version 2 to version 3. The manifest file is crucial for defining the permissions, background scripts, and other configurations for the Chrome extension. The transition to version 3 introduced several changes that were not backward-compatible, which meant that many blogs and Stack Overflow answers referenced the older version, making it difficult to find relevant solutions. I spent a considerable amount of time updating my manifest file and ensuring that it met the new requirements. Despite these hurdles, I managed to handle most cases and move forward with the project.

Photo by Scott Webb on Unsplash

Adding 3rd Party Tools for Authentication and Storage

I needed to implement authentication, and initially, I considered using Supabase. Supabase is a great tool for quickly adding authentication and other backend services to a project. However, some use cases I needed were not supported, and the pricing wasn’t in my favor. For example, I required more fine-grained access controls and file storage that were too costly with Supabase. This led me to explore other options. I will cover my experience with Supabase in more detail in another post, as it was a valuable learning experience that might benefit others looking into it.

Given my familiarity with Firebase from past projects, I decided to implement authentication using Firebase’s web SDK. Firebase offers a robust suite of tools for authentication, database management, and more. However, this decision led to unexpected issues. The Firebase web SDK does not support vanilla JS well, and combined with Chrome extensions’ strict limitations on content script loading, I faced problems I couldn’t solve. The primary issue was with the way Firebase initializes and authenticates users, which clashed with the content security policies enforced by Chrome extensions. I tried various approaches, including downloading the Firebase library locally and running it, but nothing worked. This was a significant setback and a frustrating experience.

Fine, I will use React

After spending an entire day troubleshooting, I decided to migrate my project to React. React is a powerful library for building user interfaces, and I had used it successfully in other projects. Using ChatGPT, I translated my vanilla JS code to React. This transition introduced its own set of challenges, particularly in building and running the app. I had to refactor a lot of code to fit React’s component-based architecture, and there were issues related to state management and lifecycle methods that took some time to resolve. Once I fixed these issues, I used Webpack to compile the React app for Chrome. Unfortunately, I encountered persistent compilation problems that were difficult to debug.

There is nothing like spending a weekend migrating your own side project

I never heard of Vite until today

Vite to the rescue

Through my research, I discovered that many developers faced similar issues with Webpack when compiling for Chrome extensions. The complexity and configuration overhead of Webpack made it challenging to get everything working seamlessly. That’s when I found Vite. Vite is a next-generation frontend tool that offers faster builds and a more straightforward configuration compared to Webpack. Vite solved all my issues and worked out of the box. I followed the directions on their website, and within minutes, I had everything up and running. The setup was incredibly smooth, and I was able to focus on developing features rather than wrestling with build tools. ChatGPT assisted me in generating the minimal code needed to run the app as a Chrome extension, making the process even easier.

Create a new Vite project

npm create vite@latest my-chrome-extension --template react-ts
cd my-chrome-extension
npm install vite-plugin-static-copy

Create a manifest.json file. Place the file in the ‘public’ folder

{
"manifest_version": 3,
"name": "React Chrome Extension",
"version": "1.0.0",
"description": "A simple React app as a Chrome extension",
"action": {
"default_popup": "index.html"
},
"permissions": []
}

Create a vite.config.ts file

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteStaticCopy } from 'vite-plugin-static-copy';

export default defineConfig({
plugins: [
react(),
viteStaticCopy({
targets: [
{
src: 'public/manifest.json',
dest: '.',
}
],
}),
],
build: {
outDir: 'build',
rollupOptions: {
input: {
main: './index.html',
},
},
},
});

Build the react app with Vite

npm run build

You will see a new directory created called build/ which contains the necessary files to create a chrome extension app. Once the build succeeds, head over to chrome://extensions/ , enable ‘Developer mode’ and ‘Load unpacked’ by selecting the build directory that was just created!

Vite + React working as it should :)

Conclusion

To help future developers avoid the same pitfalls, I created a template repository that anyone can fork and build projects on top of. The template includes a basic setup for a Chrome extension using React and Vite, with all the necessary configurations and scripts. By providing this template, I hope to save others the time and frustration I experienced. The repository is well-documented and includes step-by-step instructions for getting started. I hope this blog post helps those in need.

Happy coding :)

--

--