cd /news/developer-tools/stop-ocring-every-pdf-route-it-first… · home topics developer-tools article
[ARTICLE · art-114902] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Stop OCRing Every PDF: Route It First with pdf-inspector

Firecrawl has released pdf-inspector, an open-source library that classifies PDFs as text-based, scanned, image-based, or mixed, and routes only the pages that need OCR to the OCR engine. The tool, available in Python, Node.js, and WebAssembly, aims to reduce unnecessary OCR work in document-ingestion pipelines for RAG, invoice processing, and research-paper parsing. It also provides a confidence score and identifies specific pages requiring OCR, with a benchmark against a 200-document corpus.

read3 min views1 publishedAug 29, 2026

OCR is often the most expensive and slowest step in a document-ingestion pipeline. The frustrating part is that many PDFs already contain usable text, yet a naive pipeline sends every document through OCR anyway.

pdf-inspector takes a better approach: classify first, extract native text when possible, and route only the pages that actually need OCR.

The core decision is simple:

PDF arrives
  ↓
Classify the document and its pages
  ├─ native text available → extract locally → Markdown
  └─ text missing/broken   → route those pages to OCR

That small decision can remove a large amount of unnecessary OCR work from RAG ingestion, invoice processing, research-paper parsing, and document search.

The library classifies PDFs as:

TextBased

Scanned

ImageBased

Mixed

It also returns a confidence score and the specific pages that need OCR. A 40-page report with one scanned appendix does not have to become a 40-page OCR job.

Install the package:

pip install pdf-inspector

Then process a PDF:

import pdf_inspector

result = pdf_inspector.process_pdf("document.pdf")

print(result.pdf_type)
print(result.pages_needing_ocr)
print(result.markdown)

For selective OCR, the native package also exposes an OCR-aware pipeline:

ocr_result = pdf_inspector.process_pdf_with_ocr("document.pdf")
print(ocr_result.pages_routed_to_ocr)

The OCR runtime remains separate and is only touched when a page is routed to it. That keeps the default extraction path lightweight.

The same idea is available for Node.js:

npm install @firecrawl/pdf-inspector
js
import { readFileSync } from "fs";
import { processPdf } from "@firecrawl/pdf-inspector";

const pdf = readFileSync("document.pdf");
const result = processPdf(pdf);

console.log(result.pdfType);
console.log(result.markdown);

There is also a WebAssembly package for running the Rust parser locally in a browser or Web Worker:

npm install @firecrawl/pdf-inspector-wasm

This is useful when documents should not be uploaded to a parsing service just to determine whether they contain native text.

Classification is only half the project. For text-based PDFs, the extractor attempts to preserve structure such as:

The output is Markdown, which makes the library convenient for search indexing and LLM/RAG pipelines.

At a high level, the detector inspects PDF content streams for text operators such as Tj

and TJ

, and image operators such as Do

. It can scan all pages, stop early, sample a large document, or inspect a caller-provided page set.

This is a routing signal, not a promise that every PDF will be perfectly parsed. PDFs with broken encodings, text converted to vector paths, or extremely complex layouts may still need OCR or a specialized parser. The library explicitly reports encoding problems so callers can fall back instead of silently accepting bad text.

The project publishes a reproducible benchmark against a 200-document corpus. Its July 2026 results report strong reading-order and table scores as well as fast local processing. Those are project-published measurements on specified hardware—not a universal latency guarantee—so benchmark your own document mix before committing to production thresholds.

The more durable takeaway is architectural: OCR should be a fallback chosen per page, not the default chosen per file.

A conservative router might look like this:

result = pdf_inspector.process_pdf("document.pdf")

if result.pdf_type == "text_based" and result.confidence >= 0.95:
    store_markdown(result.markdown)
else:
    send_pages_to_ocr(result.pages_needing_ocr)

Your threshold should depend on the cost of a false positive. A casual knowledge base can tolerate more extraction noise than a legal or financial workflow.

If your pipeline currently OCRs every incoming PDF, classification-first routing is a small change with a clear operational payoff.

The longer version and implementation notes are available on ToolGenix.

── more in #developer-tools 4 stories · sorted by recency
── more on @firecrawl 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/stop-ocring-every-pd…] indexed:0 read:3min 2026-08-29 ·