Stop Wrestling with PDF Parsers! ocrbase Is the OCR API You Actually Need
Your PDF parser just choked on a scanned invoice again, didn't it?
You've been there. The PyPDF2 extraction returns garbled nonsense. pdfplumber crashes on image-heavy layouts. Tesseract OCR needs a PhD in configuration just to recognize a table. And don't get me started on the "enterprise" solutions that want $0.10 per page for what should be a solved problem in 2025.
Here's the dirty secret nobody talks about: most developers waste 40+ hours building fragile OCR pipelines when they could deploy a production-ready API in under 60 seconds.
Enter ocrbase β a lightweight, model-agnostic OCR API that transforms document chaos into structured data without the configuration nightmare. Built on Bun and Elysia, designed for developers who value their sanity, and scoring 94.5+ on OmniDocBench v1.5, this isn't another toy project. It's the infrastructure layer your document processing pipeline has been screaming for.
Ready to stop fighting your tools and start shipping? Let's dive deep into why ocrbase is quietly becoming the secret weapon of developers who actually get things done.
What is ocrbase?
ocrbase is a model-agnostic OCR API that standardizes document parsing across cutting-edge visual language models (VLMs). Created by Adam Majcher, it solves the fundamental fragmentation problem in modern OCR: every powerful model ships with different APIs, different deployment patterns, and different configuration headaches.
The project sits at a critical intersection. On one side, you have PaddleOCR-VL (94.5 OmniDocBench score) β the battle-tested open-source powerhouse from Baidu's PaddlePaddle ecosystem. On the other, GLM-OCR (94.6 OmniDocBench score) β the newer challenger from Zhipu AI's GLM family, optimized for document understanding with vLLM/SGLang inference. Both are state-of-the-art. Both require entirely different infrastructure to run.
ocrbase unifies them into a single, elegant HTTP API.
Built on Bun (the blazing-fast JavaScript runtime) and Elysia (the high-performance web framework), ocrbase achieves remarkable efficiency: a single container, minimal memory footprint, and response times that won't make your users check their watches. The MIT license means zero legal friction for commercial use.
Why is it trending now? Three forces converged:
- The VLM explosion: 2024-2025 saw visual language models achieve human-level document understanding, but deployment remained expert-only
- The self-hosting renaissance: Developers are rejecting SaaS lock-in and per-page pricing
- The infrastructure gap: Nobody built the "nginx of OCR" β a thin, fast layer that makes any model accessible
ocrbase fills that gap. It's not the model; it's the missing API layer that makes production OCR actually deployable.
Key Features That Separate ocrbase from the Pack
πͺΆ Featherweight Architecture
Most OCR "solutions" ship half a gigabyte of dependencies. ocrbase is a single Docker container running Bun + Elysia. We're talking megabytes, not gigabytes. This matters when you're running edge deployments, minimizing cold starts, or simply refusing to bloat your infrastructure.
π True Model Agnosticism
Switch between PaddleOCR and GLM-OCR with environment variables alone. No code changes. No dependency swaps. No retraining your team. This isn't abstract plugin architecture β it's runtime configuration:
# Point at whichever inference server is running
PADDLEOCR_URL=http://localhost:8190
GLM_OCR_URL=http://localhost:5002
The implications are massive. A/B test models in production. Fail over automatically. Upgrade models without touching application code. This is how infrastructure should work.
π Benchmark-Verified Accuracy
Both supported models score β₯94.5 on OmniDocBench v1.5 β the gold standard for document understanding evaluation. This isn't marketing fluff; it's independently verified performance on complex layouts, tables, forms, and multi-column documents.
π One-Command Deployment
docker run -d -p 3000:3000 \
-e PADDLEOCR_URL=http://localhost:8190 \
-e GLM_OCR_URL=http://localhost:5002 \
--name ocrbase ghcr.io/ocrbase-hq/ocrbase
That's it. No requirements.txt hell. No CUDA version conflicts. No Python environment archaeology. Sixty seconds to production OCR.
π§© Intuitive REST API Design
The endpoint structure follows clear semantic patterns:
| Endpoint | Purpose |
|---|---|
POST /v1/parse |
Synchronous document β text |
POST /v1/parse/async |
Asynchronous parse job |
POST /v1/extract |
Synchronous document β structured JSON |
POST /v1/extract/async |
Asynchronous extract job |
GET /v1/job/:jobId |
Poll job status and retrieve results |
Notice the symmetry? Parse for raw text, extract for structured data. Sync for immediate needs, async for scale. This is API design that respects your cognitive load.
Real-World Use Cases Where ocrbase Dominates
1. Invoice Processing Pipelines
Your finance team receives thousands of PDF invoices β scanned, photographed, digitally generated. Traditional tools fail on the scanned ones. OCR SaaS bleeds money at scale. ocrbase + GLM-OCR extracts line items, totals, vendor details into structured JSON you feed directly into your ERP. Self-hosted means predictable costs, and 94.6 OmniDocBench accuracy means fewer manual corrections.
2. Legal Document Discovery
Law firms and compliance teams process contracts, briefs, discovery documents in chaotic formats. You need full-text searchability and structured field extraction (parties, dates, clauses, amounts). ocrbase's /v1/parse creates searchable archives; /v1/extract pulls structured metadata for downstream analysis. The async endpoints handle batch processing of thousand-page document dumps without blocking.
3. Healthcare Form Digitization
Medical intake forms, insurance claims, lab reports β often handwritten, always critical. Mistakes cost lives and lawsuits. PaddleOCR-VL's robustness on Chinese and mixed-language documents (it originated in Baidu's multilingual environment) plus ocrbase's clean API gives healthcare developers a HIPAA-ready path: self-host on your infrastructure, no third-party data exposure.
4. Research Paper Archive Mining
Academic institutions and R&D teams sit on millions of PDF papers β scanned journals, preprints, conference proceedings. You need to extract citations, figures, tables, and structured metadata for knowledge graphs and LLM fine-tuning. ocrbase's queue system with Redis handles batch ingestion, while S3 staging manages the storage explosion.
5. Receipt Expense Automation
Build the next Expensify killer. Mobile app snaps receipt β uploads to ocrbase β returns JSON with merchant, date, items, tax, total. The S3 input staging handles base64 mobile uploads seamlessly; BullMQ queue prevents overload during expense report season. All self-hosted, all yours.
Step-by-Step Installation & Setup Guide
Prerequisites
ocrbase is deliberately thin β it orchestrates models, doesn't embed them. You'll need at least one inference server running:
Option A: PaddleOCR-VL Follow PaddleOCR-VL pipeline setup β typically a Python service on port 8190.
Option B: GLM-OCR with vLLM Follow GLM-OCR self-hosting guide β launches on port 5002 with vLLM or SGLang.
Option C: Both (recommended for redundancy and A/B testing)
Step 1: Quick Docker Deployment
# Pull and run the latest ocrbase image
docker run -d -p 3000:3000 \
-e PADDLEOCR_URL=http://host.docker.internal:8190 \
-e GLM_OCR_URL=http://host.docker.internal:5002 \
--name ocrbase \
ghcr.io/ocrbase-hq/ocrbase
Note: Use
host.docker.internalon Docker Desktop (Mac/Windows) to reach host services. On Linux, use the host's actual IP or run models in the same Docker network.
Step 2: Verify Health
curl http://localhost:3000/v1/parse \
-X POST \
-F "file=@test-document.pdf" \
-F "model=paddleocr"
Expected: JSON response with extracted text and metadata.
Step 3: Configure S3 Input Staging (Optional but Recommended)
For production reliability, enable S3 staging so ocrbase can handle large files, remote URLs, and base64 payloads efficiently:
docker run -d -p 3000:3000 \
-e PADDLEOCR_URL=http://host.docker.internal:8190 \
-e GLM_OCR_URL=http://host.docker.internal:5002 \
-e S3_ACCESS_KEY_ID=your-access-key \
-e S3_SECRET_ACCESS_KEY=your-secret-key \
-e S3_BUCKET=ocrbase-staging \
-e S3_ENDPOINT=https://s3.amazonaws.com \
--name ocrbase \
ghcr.io/ocrbase-hq/ocrbase
What S3 staging enables:
- Upload
Fileinputs to S3 automatically - Fetch remote document URLs and cache in S3
- Accept base64/data URL payloads without size limits
- Pass presigned GET URLs to models (faster, more reliable inference)
Step 4: Enable Async Queue Processing (Optional, for Scale)
Add Redis to unlock background job processing:
docker run -d -p 3000:3000 \
-e PADDLEOCR_URL=http://host.docker.internal:8190 \
-e GLM_OCR_URL=http://host.docker.internal:5002 \
-e S3_ACCESS_KEY_ID=your-access-key \
-e S3_SECRET_ACCESS_KEY=your-secret-key \
-e S3_BUCKET=ocrbase-staging \
-e S3_ENDPOINT=https://s3.amazonaws.com \
-e REDIS_URL=redis://host.docker.internal:6379 \
--name ocrbase \
ghcr.io/ocrbase-hq/ocrbase
Queue mode behavior changes:
POST /v1/parseβ uploads to S3, enqueues job, waits for completion, returns resultPOST /v1/parse/asyncβ returns202 { jobId }immediatelyGET /v1/job/:jobIdβ poll for status, result, or error- Bull Board dashboard at
/v1/admin/queuesfor monitoring
Step 5: Development Setup
For contributing or customizing:
# Clone the repository
git clone https://github.com/majcheradam/ocrbase.git
cd ocrbase
# Install dependencies with Bun
bun install
# Start development server with hot reload
bun dev
Bun's speed makes this genuinely pleasant β dependency resolution in seconds, not minutes.
REAL Code Examples from ocrbase
Let's examine actual patterns from the repository and documentation, with detailed explanations of how to leverage them.
Example 1: Basic Docker Deployment
# The foundational deployment command from ocrbase's Quick Start
docker run -d -p 3000:3000 \
-e PADDLEOCR_URL=http://localhost:8190 \
-e GLM_OCR_URL=http://localhost:5002 \
--name ocrbase ghcr.io/ocrbase-hq/ocrbase
What's happening here:
-ddetaches the container to run in background-p 3000:3000exposes ocrbase's HTTP API on localhost port 3000-e PADDLEOCR_URL=...and-e GLM_OCR_URL=...inject environment variables pointing to your inference servers--name ocrbasegives the container a friendly name fordocker logs ocrbaseanddocker stop ocrbaseghcr.io/ocrbase-hq/ocrbasepulls the official image from GitHub Container Registry
Critical gotcha: localhost:8190 inside the container refers to the container's own loopback, not your host machine. Use host.docker.internal (Docker Desktop) or container networking for actual deployments.
Example 2: Development Environment Bootstrap
# From the Develop section of the README
bun install
bun dev
Why this matters:
bun installresolves dependencies using Bun's npm-compatible package manager β typically 3-5x faster than npmbun devstarts the Elysia development server with hot module replacement- The entire stack (Bun runtime + Elysia framework) is optimized for edge performance β low memory, fast startup, efficient request handling
For Node.js refugees: This is intentionally minimal. No package-lock.json drama, no node_modules black holes. Bun's single-file lock (bun.lockb) and symlinking make this sustainable.
Example 3: S3-Enabled Production Configuration
# Extended deployment with all S3 environment variables
docker run -d -p 3000:3000 \
-e PADDLEOCR_URL=http://localhost:8190 \
-e GLM_OCR_URL=http://localhost:5002 \
-e S3_ACCESS_KEY_ID=your-access-key \
-e S3_SECRET_ACCESS_KEY=your-secret-key \
-e S3_BUCKET=ocrbase-staging \
-e S3_ENDPOINT=https://s3.amazonaws.com \
--name ocrbase ghcr.io/ocrbase-hq/ocrbase
The S3 staging pipeline explained:
When these four variables are present, /v1/parse transforms into a robust document ingestion pipeline:
- Direct file uploads: Client sends
multipart/form-datawithFileβ ocrbase streams to S3 bucket - Remote URL fetching: Client sends
{"url": "https://example.com/doc.pdf"}β ocrbase downloads, verifies, uploads to S3 - Base64/data URL handling: Client sends embedded payload β ocrbase decodes, uploads to S3 (bypasses request size limits)
- Presigned URL generation: ocrbase creates temporary GET URL and passes to VLM β model downloads efficiently from S3
Why this architecture wins:
- Decouples upload from processing: Client isn't blocked during inference
- Enables retry logic: S3 becomes reliable intermediate storage
- Supports massive files: No 10MB request body limits
- Improves model performance: VLMs often fetch URLs faster than processing raw bytes
Example 4: Async Job Flow with Redis Queue
When REDIS_URL plus all S3 variables are configured, the API behavior fundamentally upgrades:
# Submit async parse job β returns immediately with jobId
curl -X POST http://localhost:3000/v1/parse/async \
-F "file=@huge-document.pdf" \
-F "model=glmocr"
# Response: { "jobId": "abc-123-def" }
# Poll for completion
curl http://localhost:3000/v1/job/abc-123-def
# Response patterns:
# { "status": "pending" } β still processing
# { "status": "completed", "result": { ... } } β success
# { "status": "failed", "error": "..." } β handle gracefully
Queue architecture deep dive:
- BullMQ (Redis-based) manages job distribution, retries, and dead-letter handling
POST /v1/parse(non-async) becomes a blocking wrapper: enqueue β wait β return β simpler client codePOST /v1/parse/asyncenables true async architectures: webhook callbacks, serverless functions, event-driven pipelinesGET /v1/job/:jobIdprovides idempotency β safe to retry polls, no duplicate processing- Bull Board at
/v1/admin/queuesgives operators visibility: job counts, failure rates, processing latency
Missing Redis or S3? The API gracefully degrades: direct model calls still work, async endpoints return 503 Service Unavailable with clear messaging. This is thoughtful fallback design.
Advanced Usage & Best Practices
Model Selection Strategy
| Scenario | Recommended Model | Rationale |
|---|---|---|
| Mixed Chinese/English documents | PaddleOCR-VL | Baidu's multilingual heritage, robust CJK handling |
| Maximum accuracy priority | GLM-OCR | 94.6 vs 94.5 OmniDocBench, newer architecture |
| GPU-constrained inference | PaddleOCR-VL | Often lighter weight, broader deployment optimization |
| Complex table structures | GLM-OCR | GLM's document-specific fine-tuning excels at layout |
Performance Optimization
Enable both S3 and Redis for production loads. The direct path works for testing, but queue mode prevents request timeouts on slow documents and enables horizontal scaling.
Use model parameter explicitly. Don't rely on defaults; being explicit prevents surprises when you add models or change configurations.
Monitor Bull Board. That /v1/admin/queues endpoint reveals queue depth, job duration distributions, and failure patterns. Set up alerts on queue depth > 100 or failure rate > 1%.
Implement exponential backoff on job polling. Don't hammer GET /v1/job/:jobId every 100ms. Start at 1s, double to 2s, 4s, cap at 30s.
Security Hardening
- Run inference servers on private networks, expose only ocrbase
- Use S3 bucket policies restricting access to ocrbase's IAM role
- Rotate presigned URL expiration to minimum viable duration
- Enable Bull Board authentication before exposing to any network
Comparison with Alternatives
| Feature | ocrbase | AWS Textract | Google Document AI | Azure Form Recognizer | Self-hosted Tesseract |
|---|---|---|---|---|---|
| Self-hosted | β Yes | β No | β No | β No | β Yes |
| Model agnostic | β Any VLM | β Proprietary | β Proprietary | β Proprietary | β Tesseract only |
| OmniDocBench score | 94.5-94.6 | Unknown | Unknown | Unknown | ~70-80 |
| Per-page cost | $0 (infrastructure only) | $0.0015-0.06 | $0.0015-0.05 | $0.0015-0.05 | $0 |
| Setup complexity | One Docker command | IAM, SDK, regions | GCP project, auth | Azure subscription, keys | Compilation nightmare |
| Async/batch processing | β Built-in | β Yes | β Yes | β Yes | β Manual |
| Structured JSON output | β
/v1/extract |
β Yes | β Yes | β Yes | β Raw text only |
| Open source | β MIT | β No | β No | β No | β Apache 2.0 |
| Speed (runtime) | Bun β extremely fast | Cloud latency | Cloud latency | Cloud latency | Native, but single-threaded |
The verdict: Cloud APIs win on zero-setup for prototypes. Tesseract wins on "it's free and I have time." ocrbase wins when you need production scale, data sovereignty, model flexibility, and cost predictability.
FAQ
What models does ocrbase support?
Currently PaddleOCR-VL and GLM-OCR, with a plugin architecture designed for easy extension. Both score β₯94.5 on OmniDocBench v1.5.
Do I need GPU for ocrbase itself?
No. ocrbase runs on CPU-only infrastructure. The GPU requirement is for the inference servers (PaddleOCR-VL or GLM-OCR with vLLM/SGLang), which you deploy separately.
Can I use ocrbase without Docker?
Yes β bun install && bun dev works for development. Production Docker deployment is strongly recommended for consistency and isolation.
What file formats are supported?
The supported formats depend on your underlying VLM. Both PaddleOCR-VL and GLM-OCR handle PDF, PNG, JPEG, and TIFF. Check model documentation for specific limitations.
Is there a rate limit?
ocrbase itself doesn't enforce rate limits. Throughput depends on your inference server capacity and whether you've enabled Redis queue mode for load smoothing.
How do I handle failures in async jobs?
Poll GET /v1/job/:jobId β completed jobs include result, failed jobs include error with diagnostic information. Bull Board provides operational visibility.
Can I contribute new models?
The MIT-licensed codebase welcomes contributions. The model-agnostic architecture means adding a new VLM requires implementing a standard adapter interface.
Conclusion
Document OCR shouldn't require a dedicated DevOps team.
ocrbase proves that the right abstraction layer β thin, fast, and genuinely flexible β can transform cutting-edge AI from a science project into production infrastructure. In a market flooded with overpriced SaaS black boxes and underpowered open-source tools, it delivers the rare combination of state-of-the-art accuracy, developer-friendly deployment, and infrastructure independence.
The 94.5+ OmniDocBench scores aren't theoretical. The one-command Docker deployment isn't demo-ware. The model agnosticism isn't roadmap vapor. This is working code that solves real problems today.
My take? If you're building anything that touches document processing β expense automation, contract analysis, archival search, form digitization β you owe yourself 15 minutes to deploy ocrbase and compare it against your current stack. The time savings compound. The cost savings multiply. And the sanity preservation? Priceless.
Ready to stop wrestling with PDF parsers?
π Star ocrbase on GitHub, deploy your first container, and join the developers who've discovered that OCR infrastructure can actually be... pleasant.
The code is waiting. Your documents are waiting. Go extract some structured data.