DEV Community

Neil
Neil

Posted on

How to Structure a Production-Ready Chrome Extension (Manifest V3)

I've built several Chrome extensions over the past few years and kept running into the same problem.

Most Chrome extension templates are fine for a quick demo but fall apart when you try to build a real product.

As soon as you introduce things like:

  • popup UI
  • side panel UI
  • content scripts
  • background service workers
  • message passing
  • storage
  • API calls

the architecture gets messy very quickly.

The first couple of extensions I built ended up with logic scattered between popup scripts, content scripts, and the background worker. It worked, but it quickly became difficult to maintain as the extension grew.

After rebuilding the same structure multiple times, I eventually settled on an architecture that works reliably for production extensions.

The Basic Architecture

The architecture that has worked best for me looks like this:
Building Neurolink The Browser Extension
Each layer has a clear responsibility.

Content Scripts

Content scripts stay very thin and mainly extract page data.

They should avoid business logic whenever possible.

Their job is simply to interact with the webpage and send data to the extension runtime.

Background Service Worker

The background service worker becomes the central coordinator for the extension.

It typically handles:

  • API calls
  • authentication
  • storage
  • privileged extension logic
  • message routing

Keeping this logic centralized prevents extension code from becoming fragmented.

UI Layer (Popup & Side Panel)

The UI layer is purely presentation.

Popup and side panel components communicate with the background worker through message passing.

This keeps UI code simple and avoids mixing extension logic with interface logic.

Example Project Structure

The project structure I now use looks like this:

src/
  popup/
  sidepanel/
  options/
  background/
  content/
  core/
    messaging/
    storage/
    api/
    auth/
    logging/
Enter fullscreen mode Exit fullscreen mode

Separating UI, extension runtime, and shared utilities makes the codebase much easier to maintain.

This structure allows the extension to grow without turning into a tangled codebase.

Why This Structure Works

A few principles made the biggest difference:

  • Content scripts stay thin
  • Background worker handles privileged logic
  • UI stays separate from extension logic
  • Shared systems live in a core layer

Once these boundaries are clear, the extension becomes much easier to reason about.

Turning This Into a Reusable Starter

After rebuilding this architecture several times, I eventually packaged it into a reusable starter kit called NeuroLaunch.

It includes:

  • popup UI
  • side panel UI
  • background worker
  • message passing layer
  • storage abstraction
  • API helpers
  • authentication module
  • example extension feature

If you're interested, you can check it out here:

https://stackfactory.gumroad.com/l/neurolaunch

The goal was simply to create a clean extension foundation so developers can focus on building features instead of rebuilding boilerplate.

Final Thoughts

Chrome extensions are deceptively simple at first.

But once you combine UI, content scripts, background workers, and APIs, the architecture matters a lot.

Hopefully this breakdown helps anyone building production Manifest V3 extensions.

I'm always interested to see how other developers structure their extension projects.

Top comments (0)