DEV Community

Cover image for I built a free JSON Formatter & Validator with Angular 21 and Monaco Editor
Fazeel Mehar
Fazeel Mehar

Posted on

I built a free JSON Formatter & Validator with Angular 21 and Monaco Editor

Working with JSON every day, I found myself constantly switching between browser tabs to format messy payloads from APIs. Every tool I used either had ads everywhere, required signup, or sent my data to a server. So I built my own.

jsonproject.com — a free, browser-only JSON formatter, validator, and auto-fixer. No ads, no signup, no data ever leaves your machine.

What it does

  • Format & pretty-print — 2, 3, 4 spaces, tabs, or compact mode
  • Validate against RFC 8259 with inline error markers
  • Minify for production payloads
  • Auto-fix broken JSON — trailing commas, single quotes, unquoted keys
  • Fetch JSON from a URL — paste an API endpoint and format the response instantly
  • Drag-and-drop file upload
  • Format history — last 20 operations saved in session
  • Dark mode
  • Monaco Editor — same editor as VS Code, with full syntax highlighting

Tech stack

  • Angular 21 with SSR and prerendering
  • Monaco Editor via ngx-monaco-editor-v2
  • Tailwind CSS for styling
  • TypeScript throughout

The interesting parts

Monaco Editor in Angular SSR

The trickiest part was getting Monaco Editor to work with Angular's server-side rendering. Monaco is a browser-only library — it directly accesses window, document, and the DOM. Running it on the server causes everything to crash.

The fix: wrap the entire formatter component with ngSkipHydration and guard all Monaco initialization behind isPlatformBrowser():

if (isPlatformBrowser(this.platformId)) {
  // Monaco-specific code here
}
Enter fullscreen mode Exit fullscreen mode

And in the template:

<app-formatter ngSkipHydration></app-formatter>
Enter fullscreen mode Exit fullscreen mode

This lets Angular prerender the shell HTML on the server while Monaco initializes fully on the client.

Auto-fix engine

The auto-fixer handles the most common JSON mistakes developers make:

private attemptFix(input: string): string {
  let s = input.trim();
  // Remove trailing commas before } or ]
  s = s.replace(/,(\s*[}\]])/g, '$1');
  // Convert single quotes to double quotes
  s = s.replace(/'([^']*)'(\s*:)/g, '"$1"$2');
  s = s.replace(/:\s*'([^']*)'/g, ': "$1"');
  // Quote unquoted keys
  s = s.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)(\s*:)/g, '$1"$2"$3');
  return s;
}
Enter fullscreen mode Exit fullscreen mode

It's not a full parser — it uses targeted regex passes to handle the 90% case without breaking valid JSON.

Equal editor heights

A subtle UX detail: making the input and output Monaco editors show exactly the same number of lines. Both use the same clamp height:

height: clamp(240px, 42vh, 490px)
Enter fullscreen mode Exit fullscreen mode

And critically — never use flex-1 on a Monaco editor. It sets flex-basis: 0 which overrides the explicit height and causes the editor to collapse on mobile.

Privacy

All JSON processing is 100% client-side. The app is prerendered static HTML served from Hostinger. No backend, no database, no analytics on the JSON content. Google Analytics only tracks page views.

Try it

jsonproject.com — free, no signup, works on mobile too.

Would love feedback — what features would you add? Drop a comment below.

Top comments (0)