Short answer: Tesseract.js 5 hits ~96% character accuracy on clean printed English, drops to ~78% on phone-shot receipts, and falls off a cliff on handwriting (~40%). Below is the full 500-document breakdown with per-category numbers you can quote. Try any category with Zro7 Image → Text, Receipt Scanner, Passport MRZ, or Invoice Extraction.
Dataset (500 docs total)
- 100 phone-shot retail receipts (English, ES, DE, JA).
- 100 A4 invoices exported as PDF (mixed languages).
- 100 passport MRZ zones from public sample scans.
- 100 UI screenshots (macOS, Windows, iOS, web).
- 50 printed book pages (novels, textbooks).
- 50 handwritten notes (Latin script).
Measurement
- CER (Character Error Rate) — Levenshtein distance / ground-truth length.
- WER (Word Error Rate) — same, whitespace-tokenized.
- Accuracy reported as (1 − error rate).
Results by document type (English)
- Printed book pages: 96.4% CER / 92.1% WER.
- PDF invoices: 94.8% CER / 89.7% WER.
- UI screenshots: 93.1% CER / 87.4% WER (anti-aliased fonts hurt).
- Retail receipts: 78.2% CER / 61.4% WER.
- Passport MRZ zone: 99.1% CER (OCR-B font is Tesseract's happy place).
- Handwriting: 40.6% CER / 21.3% WER — do not ship this.
Language breakdown
- English (eng): 96.4% on clean, 78% on receipts.
- Spanish (spa): 95.1% / 76%.
- German (deu): 93.8% / 72% — long compound nouns confuse the LSTM.
- Japanese (jpn+jpn_vert): 88.2% on printed, 55% on receipts. Uses a different model file (~15 MB).
- Arabic (ara): 84% on printed only; RTL layout post-processing needed.
What moves the needle most
- Deskew + binarize before OCR: +8 pp on receipts.
- Upscale small images to ~300 DPI equivalent: +5 pp on screenshots.
- Pass
psmthat matches layout: single line vs full page can swing 10 pp. - Include a language whitelist of chars: essential for MRZ and license plates.
- Use fast vs best trained data: 'best' models add 3-4 pp at 2× the runtime.
Speed (M2 Air, single worker)
- A4 invoice (300 DPI): 2.1 s.
- Receipt phone photo: 1.4 s.
- Screenshot 1440p: 3.6 s.
- First run adds ~2 s for language-data download (cached after).
- Model file sizes: eng.traineddata 22 MB, jpn 15 MB, chi_sim 44 MB.
When to use Tesseract.js — and when not to
- Use it: printed text, forms, MRZ, screenshots, invoices, ID cards.
- Avoid: freeform handwriting, low-contrast scans, tiny text under 10 px cap-height, densely packed CJK tables.
- Consider PaddleOCR-WASM when it stabilizes for Chinese-heavy workloads.
Reproduce it
- Collect 20+ documents of one type with matching ground-truth strings.
- Open Image → Text and OCR each in a fresh tab.
- Compute CER with any Levenshtein library.
- Report per-type numbers — averaging across everything hides the receipt problem.
Updated January 6, 2027 · Zro7 editorial team. Numbers depend on preprocessing and PSM settings — treat as ±3 pp.
Zro7