API tooling · developer productivity · 2026 · Solo — product framing, diff engine, TDD, interaction design, deployment

Schema Ledger

A three-panel compare instrument that turns two JSON Schema versions into an exact compatibility verdict with copy-ready migration guards.

The problem

API developers versioning JSON Schema contracts must manually audit backward compatibility across potentially hundreds of fields — a tedious, error-prone process with no standard tooling. Schema Ledger accepts two JSON Schema (Draft 7) documents, runs a recursive structural diff, and surfaces exact change severity: BREAKING_REMOVED (field deleted), BREAKING_TYPE (incompatible type change), BREAKING_NARROWED (union type shrunk), BREAKING_REQUIRED (optional field became required), ADDITIVE (safe new optional field), WIDENED (union expanded — non-breaking), and NESTED (recursive object changes). Each breaking change expands to reveal a TypeScript migration guard stub — copy-ready coercion code. The tool also detects additionalProperties constraint changes (true→false is breaking; false→true is widened). The diff engine is a pure function with 12 TDD unit tests covering all change kinds. The application is browser-local with zero external API calls, no uploads, and no accounts. Harness deploy and behavior golden-path checks passed locally and against the production Vercel deployment before this entry was added.

Architecture

Key decisions

01

Pure diff engine with TDD first

The core diffSchemas function is a pure TypeScript function with no React dependency, making it independently testable. 12 unit tests were written before the UI, covering all 8 change kinds plus nested recursion and additionalProperties constraints. The engine uses sorted type arrays to determine widening vs narrowing deterministically.

02

Compare surface archetype

This is explicitly a Compare surface — the user is weighing two schema versions against each other. The layout is three-panel: old schema editor | new schema editor | results rail. The verdict banner and severity pills give an at-a-glance answer; the change list provides field-level detail. No marketing hero was used.

03

Guard stubs as the distinctive interaction

Each breaking change row is clickable and expands a TypeScript migration guard stub with a Copy button. This turns a passive diff report into an actionable coercion checklist. Guards are generated by the pure engine, not templated at render time.

04

Slop score 1/10

Post-build audit scored 1/10 (Geist font is the Next.js default but is the right precision choice for a developer tool; no other tells fired). No feature-tile grid, no center stack, no gradient, no icon toppers, no glassmorphism. The left-rail coloring is functional severity signalling, not decoration.

Metrics

12
TDD unit tests, all passing
0
external API calls — fully browser-local
8
change kinds detected (BREAKING, ADDITIVE, WIDENED, NESTED)
1
slop audit score out of 10