Skip to content
← Back to projects

Recto

An OCR API that returns word-level geometry, not just a wall of text — plus the dashboard, API keys, and metered plans needed to sell it. One Go binary, SQLite, no external services in the request path.

Live ↗
go sqlite ocr tesseract ollama vision-models docker api

Takes PDFs and images — including whatever a phone camera produces — and returns every word with its bounding box, confidence, block and line. Document-level totals live on the result, geometry lives on each page, and result.pages is always an array so no client has to branch on what was sent.

Two engines, and the split is the product. fast runs Tesseract 5 in ~90–250 ms and gives you word boxes with confidence; precise runs a local vision model through Ollama, takes seconds, returns layout-aware Markdown and no boxes, and is what makes the paid tier worth buying. On the bundled handwriting sample fast reads “worth ridge … witrogen” where precise reads “north ridge … nitrogen”.

One Go binary with the frontend embedded, SQLite for state, no cgo, no build step, nothing external in the request path. Idle footprint is about 25 MB of RSS — the expensive parts only run while a page is actually being read. Plans, quotas, per-minute rate limits and usage metering are real and enforced; card processing is stubbed behind a single handler.

Debian is the shipped base at 398 MB and 133 ms/page. Alpine is 45% smaller at 219 MB but consistently ~65% slower on the same page — musl’s allocator against an allocation-heavy workload, and Tesseract is exactly that. Distroless reaches image parity but Ghostscript substitutes embedded PDF fonts and renders STATEMENT as 67$7(0(17, despite byte-identical binaries and a file-for-file identical resource tree; it’s kept as an experiment, not shipped.