# I built a JSON toolkit that never sends your data anywhere

> Source: <https://dev.to/sekhar_babu_1095c83b17413/i-built-a-json-toolkit-that-never-sends-your-data-anywhere-1nlm>
> Published: 2026-08-23 09:21:17+00:00

Most "paste your JSON here" tools online send that JSON to a server to

process it. For internal API responses, config files, or anything with

real data in it, that's not something I wanted to do — so I built

[JSONLinter](https://jsonlinter.io), a JSON toolkit where literally

everything happens client-side.

It started as a validator/formatter, then grew into 42 tools across six

categories:

There's also an optional AI assistant on the validator page — it's

bring-your-own-key (OpenAI or Anthropic), and since there's no backend at

all, the key and your JSON go straight from your browser to the provider.

I never see either.

Stack is React 19 + TypeScript + Vite, Tailwind v4 for styling, CodeMirror

6 for the editor. A few things I had to solve that were more interesting

than expected:

**Prerendering without SSR.** I didn't want to take on a Next.js-style

server just to get real HTML for crawlers. Instead, the build runs a

headless Chromium pass (Playwright) over every route after `vite build`

and saves the fully-rendered output to `dist/<route>/index.html`

. Crawlers

get real content and correct per-page meta tags on first paint; once JS

loads, React takes over exactly like a normal SPA. No server, no

hydration mismatches to worry about.

**Structural JSON diff.** A text diff on two JSON documents is mostly

useless because key order doesn't matter semantically. The diff tool

parses both sides and compares the actual structure, so reordering keys

shows as no change, but changing a value does.

**Selection highlighting, CodeMirror edge case.** CodeMirror renders its

selection layer *behind* the text layer (z-index -2, deliberately, so

glyph rendering stays crisp), while the active-line highlight paints on

the text layer itself. If the active-line background is opaque, it

completely hides the selection highlight on whatever line your cursor is

on — which is every line right after a double-click. Fix was making the

active-line background translucent instead of a solid fill, so it blends

with the selection color underneath instead of occluding it. Took a while

to track down since "selection isn't visible" and "double-click doesn't

work" looked like different bugs at first.

It's live at [jsonlinter.io](https://jsonlinter.io) — no signup, no

account, nothing to install. Would genuinely appreciate feedback, especially

on anything that feels missing compared to tools you already reach for.
