Skip to content

pdf-inspector

PDF structure, built for speed.

A Rust-powered, open-source parser that classifies PDFs in milliseconds and turns native text into clean, position-aware Markdown — because ~54% of PDFs never needed OCR. Runs fully local. Use it from Node.js, Python, the browser (WebAssembly), or the bundled CLI.

pdf-inspector

Try it in your browser

Powered by @firecrawl/pdf-inspector-wasm. Drop a PDF to see its detected type and Markdown output — your document never leaves this tab.

Drop a PDF here, or click to browse

Parsing runs locally in your browser — files are never uploaded

PDFMarkdownType detectionMulti-columnTablesCJK ready

pdf-inspector

What is pdf-inspector

The open-source PDF parsing engine from Firecrawl — and the first gate of any hybrid OCR pipeline

pdf-inspector is an open-source library written in Rust that solves the most common document problem of the LLM era: figuring out whether a PDF can be read directly, extracting it locally when possible, and reserving expensive OCR for pages that truly need it.

It classifies a PDF as TextBased / Scanned / ImageBased / Mixed in about 10–50ms with a confidence score and an exact list of pages needing OCR. For the ~54% of PDFs that are native text, it completes extraction and Markdown conversion locally in under 200ms — no OCR models loaded, no external services called, not a single byte uploaded.

One parse, reused everywhere: the document is loaded once, and detection, layout analysis, table recognition, and Markdown rendering all share that single parse.

It is engineered for real-world, messy PDFs: CID/Type0 fonts decoded through ToUnicode CMaps with CJK CMaps embedded; multi-column newspaper layouts reconstructed into correct reading order; tables recovered through both rectangle drawing ops and alignment heuristics; broken font encodings flagged so callers can route those pages to OCR.

Read the full introduction →

pdf-inspector

Core capabilities

Six things a focused PDF toolchain genuinely does well

detector.rs

📄 Document classification

Identifies TextBased, Scanned, ImageBased, or Mixed PDFs in ~10–50ms, with a 0–1 confidence score and per-page signals for downstream routing.

layout.rs

🧭 Reading order reconstruction

Rebuilds multi-column and newspaper layouts from positioned text while preserving logical flow across the page. RTL text supported.

tables/

📊 Table structure recovery

Combines rectangle drawing ops, line grids, and alignment heuristics to recover cells, financial tables, and continuations across pages.

tounicode.rs

🔤 Font decoding

Decodes CID and Type0 fonts through ToUnicode CMaps, with fallbacks for common embedded encodings; broken decodings are flagged for OCR fallback.

markdown/

📝 Semantic Markdown

Emits headings (scaled by font size), lists, code blocks, bold/italic, links, tables, page markers — token-efficient output ready for LLMs.

napi/ · wasm/

📦 Packaged for your stack

Install from npm, PyPI, or crates.io. The WASM build is single-threaded with no cross-origin isolation required; the npm package ships TypeScript types and a CLI.

pdf-inspector

One parse. Clear stages.

From raw bytes to structured Markdown in five stages

1

Detect

Samples rendered page pixels to classify the document in 10–50ms, listing exactly which pages need OCR. Only need the verdict? Stop at detectPdf.

2

Extract

Pulls every text run out of the content stream with position, font, and size; CID/Type0 fonts are decoded via ToUnicode CMaps into real Unicode.

3

Lay out

Reassembles fragments into lines, paragraphs, and reading order — multi-column layouts snap back into place, RTL handled correctly.

4

Tabulate

Dual-mode detection (drawn rectangles + text alignment heuristics) recovers cells, financial tables, and cross-page continuations.

5

Emit Markdown

Serializes headings, lists, tables, links, emphasis, and page markers into clean GitHub-Flavored Markdown, ready for RAG or fine-tuning pipelines.

💡 Just need routing? Call detectPdf/detect_pdf and skip all extraction work.

pdf-inspector

Measured on real documents

Against liteparse, opendataloader, and markitdown — fast and accurate

🏆 Top overall score

Official opendataloader-bench benchmark (200 real PDFs): 0.875 overall — #1, leading reading order (0.915) and table TEDS (0.814).

🚀 An order of magnitude faster

The full 200-document corpus runs in 0.470 seconds — liteparse takes 0.750s, opendataloader 2.569s, pymupdf4llm and markitdown over 16s each.

🔒 Cost-aware architecture

Classify first, extract second: native-text PDFs convert locally, only the pages that need OCR get sent there. No models, no services — the WASM build never leaves the device.

See the full benchmark →

pdf-inspector

Quick start

From your first command to every binding

pdf-inspector

FAQ

Common questions about classification, privacy, performance, and licensing.

What is pdf-inspector?

pdf-inspector is an open-source Rust library by Firecrawl for PDF classification, text extraction, and Markdown conversion. It detects whether a PDF is text-based or scanned in milliseconds, converts native-text PDFs into clean, position-aware Markdown, and serves as the parsing engine of Firecrawl's hybrid OCR pipeline.

What do the four PDF types mean?

TextBased (native text) extracts directly; Scanned and ImageBased require OCR; Mixed has some of both. Every result includes a confidence score and per-page details telling you exactly which pages need OCR.

Are my files uploaded?

No. pdf-inspector parses entirely locally: the Rust/Python/Node versions run on your device, and the browser version uses WebAssembly inside the page. Files never leave your device. The demo on our home page works exactly this way.

Does it handle scanned PDFs?

The web demo does not include OCR and will tell you so explicitly. The native packages offer selective OCR (optional): only pages rejected by quality checks go to OCR while everything else stays on the fast local path, with per-page provenance (native / ocr / fused).

How fast is it?

Classification takes ~10–50ms; a full pass over a text-based PDF finishes within 200ms. In the official opendataloader-bench, the entire 200-document corpus completed in 0.470 seconds — about 37% faster than liteparse and over 30× faster than markitdown. See the benchmark page.

How does it compare to markitdown?

On the same benchmark: overall 0.875 vs 0.589, headings 0.788 vs 0.000 (markitdown barely recovers heading levels), and speed differs by more than an order of magnitude. See the comparison page.

Is it open source? Can I use it commercially?

Fully open source under the MIT License — free to use, modify, and commercialize. Repository at github.com/firecrawl/pdf-inspector.

Which languages can I use it from?

Rust (pdf-inspector), Node.js (@firecrawl/pdf-inspector), Python (pdf-inspector), the browser (@firecrawl/pdf-inspector-wasm), plus the bundled CLIs: pdf2md and detect-pdf. See the install page.

Try & install

Drop in a PDF,
get the verdict and the Markdown.

Parse one in your browser first, or install it into your project or service.
Millisecond classification, multi-column reconstruction, table recovery, fully local,

Stop paying OCR prices for the PDFs that don't need it.