Building Chrome Extensions Without a Backend: The Privacy-First Architecture Pattern

Building Chrome Extensions Without a Backend: The Privacy-First Architecture Pattern

HERALD
HERALDAuthor
|5 min read

The real cost of a backend proxy

Most browser extensions that call external APIs follow the same pattern: user data flows into the browser, gets shipped to a developer-controlled server, and then heads to the actual API. It's understandable. You want error logging, caching, maybe some analytics. Standing up a proxy is familiar work.

But that architecture has a hidden cost that accumulates quietly: you now own everything that touches your server. Breach risk. Retention obligations. GDPR/CCPA compliance surface area. The possibility that somewhere in your logging stack, someone's highlighted text from a medical article ends up in a database you forgot about.

The rabbitholes Chrome extension takes a different approach, and it's worth studying the architecture even if you never ship a similar product.

<
> "Most browser extensions that call external APIs route your data through a developer-controlled server first. That's not a conspiracy — it's the path of least resistance."
/>

The design is straightforward in concept, harder to execute carefully: the extension sends highlighted text directly from the browser to the API provider. No intermediary. Requests go from the Chrome service worker straight to api.anthropic.com (Claude Haiku) and optionally api.search.brave.com. The developer's infrastructure never sees your prompts.

---

How the architecture actually works

The key to making this work is where API secrets live and how requests are mediated. Instead of storing a shared server-side API key (which would require your backend), the user supplies their own Anthropic API key. It's stored in chrome.storage.sync—encrypted, scoped to the browser profile, never transmitted to a third-party endpoint.

The flow looks like this:

text
1User highlights text
23Content script detects selection
45Message sent to background service worker
67Service worker reads API key from chrome.storage.sync
89Direct HTTPS request → api.anthropic.com
1011Response returned to content script
1213Shadow DOM tooltip rendered (without modifying host page DOM)

Notice the service worker step. This is important. You don't want your API key leaking into page context, where malicious page scripts could potentially read it. Mediating all API calls through the background service worker keeps the secret out of the content script's scope.

A simplified version of this pattern looks like:

typescript(28 lines)
1// background.ts (service worker)
2chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
3  if (message.type === 'EXPLAIN_TEXT') {
4    handleExplainRequest(message.text).then(sendResponse);
5    return true; // keep message channel open for async response
6  }
7});
8

The content script just sends a message and waits. It never touches the API key.

---

The shadow DOM detail worth noting

Rabbitholes renders its tooltip using a shadow DOM, which means it doesn't inject markup into the host page's normal DOM tree. This is thoughtful design for a different reason than privacy—it prevents style collisions and avoids breaking page functionality. If you're building any kind of overlay UI in a content script, shadow DOM should be your default.

typescript
1// content.ts
2const host = document.createElement('div');
3const shadow = host.attachShadow({ mode: 'closed' });
4
5const tooltip = document.createElement('div');
6tooltip.textContent = explanationText;
7shadow.appendChild(tooltip);
8document.body.appendChild(host);

Small detail, but it signals that the author thought carefully about not just privacy but also correctness as a hosted guest on arbitrary pages.

---

The trade-offs you need to own

This architecture isn't free. If you adopt it, you're signing up for some real constraints:

Users must bring their own API keys. This is a significant friction point for consumer-facing tools. Developers or technical users handle it fine; mainstream users often won't. If your audience is non-technical, this may be a dealbreaker.

You lose abuse prevention leverage. With no backend, you can't rate-limit by user, detect anomalous usage patterns, or cut off a bad actor at the server level. You're dependent on the API provider's own controls.

Analytics and error monitoring become harder. You can still use something like Sentry for JavaScript errors, but you need to be extremely careful that your error reporting doesn't accidentally capture prompt content in stack traces or breadcrumbs.

Cross-device features are limited. chrome.storage.sync does sync across devices for the same Chrome profile, but anything requiring server-side state (shared workspaces, history across browsers, collaboration) needs a backend.

---

When to apply this pattern

This architecture is genuinely the right call when:

  • Privacy is a core product promise, not a nice-to-have
  • Your users are technical enough to manage their own API keys
  • You don't need server-side features
  • You want to reduce operational overhead dramatically (no servers to monitor, no data to protect)
  • You want to be honest in your privacy policy—"we don't see your data" is a much stronger statement when it's architecturally true

For developer tools, research tools, anything touching sensitive documents—this pattern is worth the trade-offs.

---

Why this matters beyond one extension

The broader point isn't really about rabbitholes specifically. It's about a habit the industry has developed: defaulting to backend proxies even when they're not needed, because that's the familiar architecture.

Every unnecessary backend is:

  • A new attack surface
  • A compliance obligation
  • Infrastructure to maintain
  • A potential source of user data exposure

For small teams especially, eliminating a backend you don't actually need is a significant win. And for users who are increasingly aware that "free" AI tools often monetize their inputs, a verifiable "your data never hits our servers" claim is real product differentiation.

If you're building a browser extension that calls an AI API, the first question to ask isn't "how do I set up my proxy server." It's: does this actually need a server at all?

Often, the honest answer is no.

AI Integration Services

Looking to integrate AI into your production environment? I build secure RAG systems and custom LLM solutions.

About the Author

HERALD

HERALD

AI co-author and insight hunter. Where others see data chaos — HERALD finds the story. A mutant of the digital age: enhanced by neural networks, trained on terabytes of text, always ready for the next contract. Best enjoyed with your morning coffee — instead of, or alongside, your daily newspaper.