Forem

HelixLabs-dev
HelixLabs-dev

Posted on

I built my first Chrome extension as a CS student. Here's what actually surprised me.

I've been building web apps for a while. I thought a Chrome extension would be a weekend project.

It was not a weekend project.

I'm a CS student and I recently shipped Prompt Helix — a page-aware AI assistant that sits on any webpage. Building it taught me things that no tutorial really prepared me for. So here's the honest version.
Manifest V3 is a different world

If you're learning from tutorials, half of them are still using Manifest V2. The migration to V3 changed how background scripts work fundamentally service workers replace background pages, and service workers don't persist the way background pages did. This means you can't store state the way you're used to. I lost a solid few days figuring out why my extension kept losing context between actions.

If you're starting a Chrome extension today, go straight to the official V3 docs and ignore any tutorial older than 2023.

Content script isolation is genuinely weird
Your content script runs in the page's context but is isolated from the page's JavaScript. This sounds simple until you're trying to extract content from a dynamically rendered page and wondering why your script can see the DOM but not the data you actually want. Some pages load content after the initial render via JavaScript and your content script fires before that content exists. I handle this with truncation currently which isn't ideal but it works well enough for most pages.

Multi-provider API abstraction is harder than it sounds
Prompt Helix supports OpenAI, Anthropic, Gemini and Mistral. Each provider has different API structures, different error formats, different rate limiting behaviour, and different ways of handling streaming responses. Building a clean abstraction layer that handles all four consistently and fails gracefully took longer than the entire UI. If you're building something multi-provider, design the abstraction layer first before writing a single API call.

BYOK was the right call but adds complexity
I made the decision early to keep API keys local stored in Chrome's storage, never transmitted to my servers. This was the right privacy decision and users respond well to it. But it means every API call goes directly from the extension to the provider, which means error handling has to be airtight on the client side. There's no server layer to catch mistakes. Every edge case is the user's problem if you don't handle it properly.

The Chrome Web Store review process is opaque
You submit, you wait, you get approved or rejected with minimal explanation. I just got rejected last week for a privacy policy issue — my policy didn't explicitly cover the extension's data handling even though it covered the SaaS product. One extra section later and we're resubmitting. Build time into your launch plan for review cycles. Don't assume it's a rubber stamp.

What I'd tell myself at the start
Start with Manifest V3 documentation not tutorials. Design your abstraction layers before writing API calls. Handle errors like a paranoid person. Write your privacy policy to explicitly cover the extension not just your website. And accept that the Chrome Store review is a variable you can't fully control.

If you're thinking about building a Chrome extension, do it. It's a genuinely different development experience from web apps and the distribution through the Chrome Store. even with its quirks is real. People find your extension through search without you doing anything.
Happy to answer questions from anyone building their first extension. The rabbit holes are real but worth it.

Top comments (1)

Collapse
 
helix_labs_dev profile image
HelixLabs-dev

First Chrome extension I've ever shipped and I picked one of the harder ones apparently. If you're building or have built an extension I'd love to know what tripped you up. It feels like everyone has their own Manifest V3 horror story.