DEV Community

Cover image for I Deleted My Share Backend and Replaced It With a URL
Yash Panchal
Yash Panchal

Posted on Originally published at nitroide.com

I Deleted My Share Backend and Replaced It With a URL

Every "share" feature you've ever used is really three servers in a trench coat: a database to store the thing, an auth system to gate it, and an API to move it around. When I set out to add code sharing to NitroIDE, I had a problem: NitroIDE has no servers. The whole IDE runs in your browser — editor, live preview, console — nothing phones home. So I did the dumbest thing that could possibly work: I stuffed the entire shared project into the URL itself.

It worked so well I never built the backend.

The 30-second pitch

Open NitroIDE, write some code, hit "Copy share link." What you get looks like this:

nitroide.com/tools/codebox.html?code=eJx…(a few thousand characters)…

Send that to anyone. They open it and get your exact editor state plus a live, running preview of the code — no signup, no "view-only requires login," no expiry, no loading spinner waiting on a server. The URL is the database.

How the engine works (the whole trick in three steps)

1. Compress. When you hit share, the code is deflated in the browser itself (the same DEFLATE algorithm behind gzip, run client-side). Most HTML/CSS/JS snippets compress to a third or a quarter of their size. A typical "check out this bug" demo — a few hundred lines — lands at 2–5 KB after compression. That matters because URLs have practical length limits (browsers tolerate tens of thousands of characters, but long URLs get mangled by chat apps, email clients, and URL shorteners), so every byte counts.

2. Encode. The compressed bytes get base64url-encoded — the URL-safe variant of base64, no + or / that would break query parsing — and dropped into the ?code= query parameter. No server saw your code at any point. It went from your editor to a string in your clipboard.

3. Hydrate. On the receiving end, codebox.html reads ?code=, reverses the pipeline — base64url decode, inflate, load into the editor — and feeds the result straight into the live preview via srcdoc. No network round-trip, no "fetching shared project…" state, no dependency on a server being up. From cold open to running code in well under a second on a decent connection, most of it just page load.

That's the entire share backend: btoa plus a compressor plus a URL.

Why this fits the no-server philosophy (and what it forced)

Building this way wasn't just cheapness — it changed the design. A server-backed share feature would need link expiry, permission levels, storage quotas, abuse reporting, a privacy policy section about stored user content. The URL-share needs none of it, because there's nothing stored anywhere. Your code never sat on my disk. There's no "NitroIDE servers were breached and shared links leaked" scenario, because there are no NitroIDE servers holding your links.

But it also forced honest constraints into the product:

  • Size limits are real. URLs can't be infinite, so this is for snippets, demos, and prototypes — not your 10,000-line project. Big work still goes through Export-to-ZIP. Rather than hide this, the share dialog shows the compressed size before you copy the link, so you know when you're pushing it.
  • Share links are public by design. Anyone with the link has the code — same as a screenshot, same as a pastebin. Never put secrets, API keys, or tokens in a share link. I say this in the docs and I'll say it here: treat ?code= links like screenshots.
  • No analytics, no tracking. I genuinely cannot tell you how many times a link was opened, because nothing was stored and nothing was logged. For a privacy-positioned tool, that's a feature.

The bug that taught me the most

The v25 audit surfaced a real flaw in this pipeline: the service worker was runtime-caching every ?code= URL as a separate cache entry. Every share link anyone opened added another entry — the share engine was slowly stuffing the user's cache with garbage. The fix: cache document navigations under the bare path, ignoring the query string. It's the kind of bug that only exists because the URL is the database — worth remembering if you build anything that encodes state into URLs. Your caching layer needs to know that ?code=X and ?code=Y are the same page with different payloads.

Why I think this generalizes

The ?code= pattern is really "put the state in the address bar" taken to its logical end, and it works anywhere the state is small and compressible: playgrounds, form builders, chart configurators, regex testers. The industry default — reach for a database — is often a habit, not a requirement. Ask what breaks if the data lives in the link instead: sometimes the answer is "nothing, and now you have no storage costs, no GDPR surface for that data, and instant load times."

NitroIDE is free, runs entirely in your browser: https://nitroide.com?utm_source=devto&utm_medium=article&utm_campaign=daily-2026-09-29

The code never leaves your machine — not even to share it.

Top comments (0)