Browser-based JSON tools built to stay responsive on documents that break other online viewers. Nothing is uploaded — every operation runs locally.
Live: https://jsonic.ratnesh-maurya.com
28 tools, each on its own server-rendered route so it is individually indexable.
| Group | Tools |
|---|---|
| Inspect | Tree Viewer, Validator, Compare, JSONPath, Size Analyzer |
| Format | Formatter, Minifier, Sort Keys, Escape / Unescape |
| Transform | Flatten / Unflatten, Merge & Patch, Base64, JWT Decoder |
| Convert | To CSV, To YAML, To XML, CSV to JSON, NDJSON, To SQL |
| Generate | TypeScript, Go, Python, Rust, Java, C#, Kotlin, Zod, JSON Schema |
Every code generator merges the shape of all array elements rather than sampling the first, so keys missing from some elements come out optional rather than silently disappearing.
- Parsing runs in a Web Worker (
lib/json/json.worker.ts). The main thread never blocks onJSON.parse, so the interface stays interactive while a job is in flight. Superseded jobs are dropped by id, so fast typing never renders a stale result. - The tree is a flat row model, not a component tree (
lib/json/flatten.ts). Collapsed containers are skipped entirely during the walk, so cost is proportional to visible rows rather than document size.react-windowmounts only the rows in the viewport. - Statistics are one traversal with an explicit stack — no per-node re-serialisation, and no recursion to overflow on deep documents.
- Syntax highlighting is per visible line. Only the ~50 lines on screen are tokenized.
- Size tiers (
lib/json/types.ts) turn off live processing above 1 MB and switch the editor to a read-only virtualized view above 4 MB, where a controlled<textarea>stops being viable.
Measured on a 17 MB / 120k-record fixture (npm test): stats 63 ms, collapsed tree 4 rows in 5 ms, expanding 120k children 85 ms.
No backend. Documents never leave the browser.
- Preferences (sidebar collapsed, indent, sort keys, live mode) —
localStorage, one namespaced key. - Documents — IndexedDB (
lib/storage/documents.ts).localStoragecaps around 5 MB and writes synchronously, which is the wrong place for a JSON document. Drafts autosave on a debounce plusvisibilitychangeandpagehide, withnavigator.storage.estimate()checked before writing.
npm install
npm run dev # http://localhost:3000
npm test # correctness + performance suite
npm run typecheck
npm run buildNEXT_DIST_DIR lets a production build run alongside a dev server without the two clobbering each other's .next:
NEXT_DIST_DIR=.next-verify npm run build
NEXT_DIST_DIR=.next-verify PORT=3111 npm start| Variable | Purpose |
|---|---|
NEXT_PUBLIC_GA_MEASUREMENT_ID |
GA4 measurement id (analytics are skipped when unset) |
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION |
Search Console verification token |
lib/json/ pure logic — core, codegen, convert, structure, strings, csv, sql
lib/json/json.worker.ts the only place JSON.parse runs on user input
lib/json/modes.ts maps each tool page to a worker op and output panel
lib/tools.ts tool registry: drives nav, routes, sitemap, metadata, FAQ schema
lib/tool-icons.tsx lucide icon per tool (named imports only)
lib/storage/ IndexedDB draft persistence, one draft per tool
app/components/json/ virtualized tree, code view, editor
app/components/shell/ collapsible sidebar, top bar, tool page chrome
app/components/tools/ workbench, toolbar controls, output panels
app/components/home/ static tree preview, spotlight grid
app/<slug>/page.tsx one server component per tool
Adding a tool means one entry in lib/tools.ts, one in lib/json/modes.ts, and a
page.tsx rendering its island — the sidebar, sitemap and structured data follow
automatically.
- Icons are
lucide-react, named imports only. Next rewrites them to deep imports viaoptimizePackageImports, which lucide is on the default list for. - No animation runtime. The hero spotlight, aurora, card hover and rotating
word are CSS; the only JavaScript is one delegated
pointermovethat writes two custom properties.framer-motionwas removed in the previous pass and staying off it is deliberate. - Tool pages carry one visible line of prose. The long-form copy and the FAQ
ship in the server-rendered HTML inside collapsed
<details>— indexed, but not occupying the screen the tool needs.HowToschema was dropped: Google deprecated HowTo rich results in 2023 and retired FAQ rich results in May 2026, soFAQPagestays only because it is still parsed for page understanding.
- 🌐 Blog: https://blog.ratnesh-maurya.com/
- 💼 Portfolio: https://ratnesh-maurya.com/