Most tool sites work the same way: you upload a file, their server processes it, you download the result. Your document leaves your device for work the browser could already do — plus a round trip, a sign-up wall, and a quota. I built SopKit the other way round: 605+ tools that run entirely in the browser, on a static site with no backend at all.
In one 30-day window, that static site served 4.3M+ requests and 213K+ visits. The cost of one more visitor is approximately zero.
What the browser already has
The modern browser is a runtime most developers underestimate. Before reaching for a server, check whether the capability already exists on the client:
- File API + Streams — read and write files of any size without loading them fully into memory.
- Canvas + OffscreenCanvas — image resize, crop, convert, watermark, all on a worker thread.
- WebCrypto — hashing, encryption, and signatures with native speed. Hashing a file is a few lines:
- WebAssembly — near-native speed for heavy work: image codecs, PDF manipulation, compression.
- OPFS (Origin Private File System) — real on-disk storage for large intermediate files.
// Hash a file without uploading it anywhere
async function sha256(file) {
const buffer = await file.arrayBuffer();
const digest = await crypto.subtle.digest("SHA-256", buffer);
return [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
That function is the whole architecture in miniature: the file never leaves the device, there is no server to scale, no upload to wait for, and no private document sitting in someone else's storage bucket.
Why static wins for tools
A tool site's workload is almost perfectly suited to a static host:
- No per-request compute. Every visitor brings their own CPU. Traffic spikes cost nothing because there is nothing to scale.
- Privacy is structural, not a promise. Files stay on the device, so there is no data to leak, no retention policy to trust, no breach surface for user documents.
- Latency is one round trip less. No upload, no queue, no download. For small files the work finishes before a server round trip would even return.
- It degrades gracefully. A static site behind a CDN stays up when a database-backed app would be down.
The honest limits
A static site cannot do everything, and pretending otherwise is how you build the wrong thing:
- No accounts, no sync. Anything that needs a user record or cross-device state needs a server (or a sync service).
- No secrets. API keys and private logic cannot live in client code.
- Heavy compute drains batteries. A 4K video transcode belongs on a server or a desktop app, not a phone browser.
- Large files still hurt. The browser can stream, but a multi-gigabyte file will test patience and memory on low-end devices.
The rule I use: if the work is a pure function of the user's file and the browser has the API, keep it client-side. The moment you need shared state, secrets, or heavy compute, that is what a server is for.
The lesson
SopKit started as a small collection of tools and outgrew its original name and domain; it now lives on GitHub Pages specifically so there is no domain to renew and no server to keep alive. The architecture decision that made that possible was made on day one: when the browser can do the work, a server is a liability — in cost, in latency, and in trust. Build the server only for the work the browser genuinely cannot do.
Top comments (0)