Technology Sep 13, 2026 · 4 min read

I Counted How Many Free Dev Tools Quietly Upload Your Data. Then I Built 80 That Don't.

Paste a JWT into a "free online JWT debugger." Paste a config file into a "free JSON formatter." Then open DevTools, hit the Network tab, and watch it POST your payload to api.something-saas.com/v1/parse. I got annoyed enough to check. Of the first dozen "free" tools I tried, eight shipped data of...

DE
DEV Community
by sharefun2023
I Counted How Many Free Dev Tools Quietly Upload Your Data. Then I Built 80 That Don't.

Paste a JWT into a "free online JWT debugger." Paste a config file into a "free JSON formatter."

Then open DevTools, hit the Network tab, and watch it POST your payload to api.something-saas.com/v1/parse.

I got annoyed enough to check. Of the first dozen "free" tools I tried, eight shipped data off the device. Some had a privacy policy. Some had a privacy policy that said "we may share data with partners." Your production tokens, in a partner's S3 bucket.

Most of them weren't even doing it to be evil. They just built a Next.js app, needed the logic somewhere, and the server was already there. Formatter on the server. Base64 decode on the server. For a 3-line JSON.stringify.

The part that actually costs you

It's not just privacy theater. Server-side tooling has real costs you pay every day:

  • Latency. Round-trip to a region that isn't yours, on a connection that isn't yours. My regex tester took ~400ms to say "no match."
  • Rate limits and paywalls. Free tier hits you at 10 operations. The tool that was "free" is now a $9/mo subscription for btoa.
  • Availability. Their server goes down, your tool goes down. Great during an incident, when you actually need to decode something.
  • Offline. On a plane, on a locked-down corporate network, the tool is gone.

Every one of those problems disappears if the code runs in the browser tab you already have open.

What client-side actually means

There is no API. There is no fetch to a backend. Network stays empty except for the static assets. Concretely:

// Base64, no server. 2 lines and no data leaves the tab.
const encode = (s) => btoa(String.fromCharCode(...new TextEncoder().encode(s)));
const decode = (s) => new TextDecoder().decode(Uint8Array.from(atob(s), c => c.charCodeAt(0)));
// JWT verify with a real signature check, in-page.
// WebCrypto handles HS256/384/512 and RS/ES via importKey.
const [h, p, s] = jwt.split(".");
const key = await crypto.subtle.importKey(
  "raw", new TextEncoder().encode(secret),
  { name: "HMAC", hash: "SHA-256" }, false, ["verify"]
);
const sig = Uint8Array.from(
  atob(s.replace(/-/g, "+").replace(/_/g, "/")), c => c.charCodeAt(0)
);
const ok = await crypto.subtle.verify(
  "HMAC", key, sig, new TextEncoder().encode(`${h}.${p}`)
);

That's the whole "backend." The <input> is the API.

The interesting cases are where people assume you need a server:

Task Why people think it needs a server How it's actually done client-side
SQL formatting "Parsing is hard" Tokenizer + formatter in a Web Worker — keeps the main thread at 60fps
Image conversion "Encoding is server work" Canvas + toBlob('image/webp')
SVG to PNG "Rasterization needs a service" Draw the SVG into a canvas via a data-URI image
Regex testing "Sandboxing" It's a regex. RegExp has been in the engine forever
Hashing (SHA/MD5) "Performance" crypto.subtle, native speed

WebCrypto also gives you something the SaaS tools don't: the key never crosses the wire. A server-side JWT verifier has to receive your signing secret to check a signature. That's a much bigger deal than the payload leak.

What I built

23232322.xyz — 80+ tools, one page each, no build step. JSON formatter and validator, Base64 encode/decode, regex tester, JWT debugger with real HS256/384/512 and RS/ES256-512 verification, hash generators, UUID, URL encode/decode, diff checker, HTML minifier, and a bunch more.

No account. No upload. No analytics on your input. Source for each page is plain HTML + vanilla JS, so you can read it and confirm nothing is being sent anywhere.

How to check any tool yourself in 20 seconds

Before you trust any "free online X":

  1. Open DevTools → Network.
  2. Filter to Fetch/XHR.
  3. Use the tool with obvious dummy data ({"test":1}).
  4. If a request appears with your input in the body — that data left your machine.

Do that to my tools too. It's the point.

If a tool can't be written this way, it's because it needs a real backend. Most of them don't. They just needed somewhere to put the code.

The whole set is at 23232322.xyz.

DE
Source

This article was originally published by DEV Community and written by sharefun2023.

Read original article on DEV Community
Back to Discover

Reading List