DEV Community

J Now
J Now

Posted on

Built rabbitholes with no backend: here's what that constraint forced

Tab-switching kills reading focus. I kept hitting words I half-knew in articles — terms I'd skip past or look up in a new tab and never fully return from. I wanted explanations inline, next to the text, without leaving the page. That's rabbitholes: highlight any text, get a shadow-DOM tooltip with an explanation from Claude Haiku 4.5, then click any word in that explanation to go deeper.

The privacy architecture was the interesting design constraint. The extension needs API credentials to call Claude and optionally Brave Search. The default move for most extensions is a backend proxy — you control the server, you hold the keys, users authenticate against your service. That's also the architecture where every query your users make is visible to you.

I went the other direction. Requests go directly from the browser to api.anthropic.com and api.search.brave.com — no intermediary. Your Anthropic API key sits in chrome.storage.sync, encrypted by Chrome, tied to your account, never transmitted to any server I run. Zero telemetry, zero analytics. There's no server to breach because there's no server.

The real forcing function this created: all context has to live in the client. When you click a word in an explanation to explore it further, or drag across a phrase, or use the pencil icon to type a follow-up — all of that context travels with the shadow-DOM component, not with a session. The rabbit-hole counter (tracking how many hops deep you've gone) is local state. Nothing is persisted or synchronized through me.

Manifest V3 reinforces this — service worker, no persistent background process, nothing running between your sessions.

The friction cost is real: you paste in your own API key. What you get is an architecture where data collection isn't a policy choice I can reverse — it's structurally impossible from the start.

https://github.com/robertnowell/rabbitholes

Top comments (0)