Ledger

Buyers were comparing supplier quotes by hand in Excel, one tab per supplier. Ledger ingests the quotes however they arrive and lines them up against the original request so the differences are the only thing on screen.

Year
2025
Role
Design and build
Built with
TypeScript, Next.js, Postgres, DuckDB
Ledger interface
400+
line items per sheet
9 min
median review, from 2 hrs
6
input formats accepted

The problem

A sourcing request goes out as a structured sheet and comes back as whatever the supplier felt like sending: a rewritten spreadsheet, a PDF, sometimes a photo of a printout. Buyers were rebuilding a comparison table by hand for every deal.

The naive fix is a strict upload template. Suppliers ignore templates, so that just moves the manual work onto the person chasing them.

Approach

Accept anything, then make correction cheap. Every ingested cell keeps a pointer back to where it came from, so when the parser guesses wrong the buyer sees the original next to the guess and fixes it in one keystroke.

Comparison runs in DuckDB in the browser. Once the quotes are aligned, re-pivoting 400 rows across eight suppliers is instant, which is what makes the tool feel like a spreadsheet rather than a form.

What I would change

Confidence scores were surfaced too early. Buyers either trusted them completely or ignored them entirely, and neither is useful. Showing the source excerpt instead moved the needle far more than showing a number.

Next project

Spec Diff