mrkeyoor.com_
Thu 17 Sept 20:45 UTC
Dataevaluationupdated 26 Aug 2026

pdf-inspector review

PDF Inspector is a Rust parser that classifies PDFs, extracts positioned text, and converts native text into Markdown. It has Rust, command-line, Python, Node.js, and browser packages, with selective OCR available on native paths for pages that lack usable text.

+129stars / 7d
Verdict

Our PDF Inspector run passed 100 of 101 tests, with the lone failure raising an encrypted-PDF error after a 474-second install. It is a strong candidate for local native-text extraction and selective OCR routing, provided you test the fonts and tables that matter to your corpus. Add an explicit encrypted-file path and output checks before placing its Markdown into search, accounting, or legal workflows.

We ran it

Lab card: what happened when we ran pdf-inspectorScreenshot of pdf-inspector (firecrawl.github.io/pdf-inspector)
Departure-board graphic showing what PDF Inspector can and cannot do, plus measured install, build, and test results.
Install✓ · 474s36 packages · 51 MB
Build✓ · 8s
Tests✗ · 59s100 passed · 1 failed of 101 (pytest)
Known vulns0(pip-audit)
Repo312 files~106,900 lines of source · 15.6 MB · 6 CI workflows · tests dir

Answers from our run

Does pdf-inspector build from source?

Dependencies installed in 474 seconds (36 packages), and the build succeeded in 8 seconds. We cloned commit 23cf1ad into a clean Debian container with 3 CPUs and no project-specific setup.

Do pdf-inspector's tests pass?

Not all of them: 100 of 101 passed and 1 failed when we ran the project's own test command (pytest). Some failures need services or credentials a bare container does not have.

Does pdf-inspector have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use pdf-inspector?

Pipelines that must accept encrypted PDFs without a separate password and fallback path: our fixture test raised ValueError: PDF is encrypted.

What are the alternatives to pdf-inspector?

PyMuPDF, pypdf, MarkItDown. Our PDF Inspector run passed 100 of 101 tests, with the lone failure raising an encrypted-PDF error after a 474-second install.

Setup3/536 packages used 51 MB, but installation took 474 seconds
Docs4/5Binding and OCR guides are detailed; routing policy is still open
Community4/516,734 stars with August issue and release activity
Maturity3/5v1.15.0 spans four runtimes; correctness reports need care

Discussed on

  1. hnPdf-inspector: Rust lib for PDF inspection, classification, and text extraction5 points
  2. hnFast Rust Library for PDF text extraction5 points
  3. hnPdf-inspector: The rust-powered open-source PDF parser for AI3 points

Who it’s for

Document pipelines that need to route native-text and scanned pages differently.
Developers extracting headings, lists, tables, links, and reading order into Markdown.
Python, Node.js, Rust, or browser applications that need local PDF parsing.
Teams willing to validate output against their own document types before automating downstream decisions.

Who it’s NOT for

Pipelines that must accept encrypted PDFs without a separate password and fallback path: our fixture test raised ValueError: PDF is encrypted.
Browser-only applications that need local OCR: the README keeps the browser build on pure extraction, while OCR is exposed through native entry points.
Workloads where silent character errors are unacceptable without verification: issue 457 reports wrong Type0 font decoding with no error.
Financial extraction that treats every table cell as authoritative: issue 419 reports separate numeric columns merged into one cell in a sample document.

Setup reality

Our Python sandbox install succeeded in 474 seconds, adding 36 packages and using 51 MB. The build succeeded in 8 seconds. Tests ran for 59 seconds: pytest reported 100 passed and 1 failed out of 101, plus 9 passing subtests.

The single failure processed the included encrypted-secret123.pdf fixture and raised ValueError: PDF is encrypted. The log does not show password input or a fallback. Pip-audit found 0 known vulnerabilities in the installed packages.

Plain extraction needs no hosted account. Selective OCR needs separately installed PDFium and ONNX Runtime libraries when a page is routed, plus cached model files. Browser WebAssembly stays on extraction, while Python and Node packages include OCR integration code without bundling those external runtimes.

PDF Inspector separates native text from pages that need OCR

PDF Inspector first classifies a document as text based, scanned, image based, or mixed. It can then extract positioned text, infer reading order, and produce Markdown with headings, lists, links, tables, and page breaks. Page-level results tell a caller which pages may need OCR. This is useful in an ingestion pipeline because native text should not be sent through an image recognizer merely because one page is a scan.

The core is Rust, with packages for Python, Node.js, browser WebAssembly, and native Rust callers. Command-line programs expose detection and conversion as JSON or Markdown. Our checkout contained 312 files and about 106,900 source lines in 15.6 MB. That line count includes bindings, fixtures, generated or supporting code as captured by the harness; it describes repository scale rather than parser speed or extraction quality.

Native extraction stays light until a page reaches OCR

The default parser reads PDF content streams, font mappings, drawing operations, links, and form fields without loading an OCR model. Its Markdown layer groups lines, detects columns, uses font sizes for heading levels, identifies monospace blocks, and attempts both rectangle-based and alignment-based tables. A browser can run that parsing through WebAssembly without sending the document to a server.

Selective OCR is a native feature with more moving parts. Rust, the CLI, Python, and Node.js can render selected pages through PDFium and recognize them with PP-OCRv6 Small through ONNX Runtime. Those libraries and model files remain external. The 51 MB from our Python install did not include an activated OCR runtime or downloaded model cache, so operators should budget and pin those assets separately.

What happened when we ran it

Our fresh Python 3.12 Debian sandbox installed commit 23cf1ad in 474 seconds. The environment added 36 packages and occupied 51 MB. The build then succeeded in 8 seconds. The repository had 6 CI workflow files, a tests directory, and no Dockerfile. Pip-audit reported 0 known vulnerabilities among the installed Python packages.

Pytest ran for 59 seconds and reported 100 passed and 1 failed out of 101, plus 9 passing subtests. The failure came from the parametrized fixture encrypted-secret123.pdf. Calling pdf_inspector.process_pdf raised ValueError: PDF is encrypted. The log tail does not show whether a password-aware API exists elsewhere or why that fixture was expected to pass, so our finding stops at the observed exception.

Encrypted files need a policy before ingestion starts

A document pipeline cannot treat that exception as a rare curiosity. Password-protected PDFs appear in financial, legal, and customer-upload workflows. Decide whether the service rejects them with a useful message, accepts a password through a separate trusted channel, or routes them to another parser. Never record an empty Markdown string as a successful extraction because downstream search will quietly omit the document.

Open issue 254 asks for an OCR routing guide with confidence thresholds and fallback behavior for corrupted and encrypted PDFs. The API already reports classification, confidence, and page suggestions, but the project does not yet prescribe the business decision around those fields. Our 100 passing tests show wide exercised behavior; the 1 encrypted fixture failure shows why callers still need a document-level error state.

Font and table output must be checked against the source

PDF text is drawing instructions, not a semantic document tree. PDF Inspector reconstructs structure from coordinates, fonts, operators, and shapes. That can work well while still producing a valid-looking wrong value. Issue 457 reports Type0 Identity-H text with a ToUnicode map decoding individual characters incorrectly without an error. Issue 456 reports invisible or occluded text surviving extraction in some cases.

Tables carry higher stakes. Issue 419 describes distinct numeric columns merging into one cell for a row in a customs statistics PDF. A Markdown table can be syntactically perfect and numerically false. For invoices, filings, or research data, compare cell counts and critical values against rendered pages. The 59-second suite is a useful baseline for the project checkout, but your corpus needs regression fixtures for its fonts, languages, scans, and table styles.

Four language surfaces widen the testing matrix

Python accepts a path and returns a result object. Node.js reads bytes and exposes synchronous native extraction plus asynchronous OCR. Rust offers option builders and feature-gated OCR, while browser WebAssembly works with byte arrays and stays on extraction. The CLI can emit raw Markdown, positioned items, compact output, selected pages, and classification JSON. This range makes the parser easier to place in an existing stack.

It also creates packaging choices. Native Node builds are published for named Linux, macOS, and Windows targets. OCR requires runtime library paths and model caching. A browser worker avoids server uploads but cannot follow the same OCR route described for native packages. Keep one set of golden PDFs and compare outputs across the exact binding and version you deploy instead of assuming every surface behaves identically.

Active releases do not remove corpus-specific risk

GitHub listed 16,734 stars, 182 combined issues and pull requests, and a last push on August 21, 2026. Release v1.15.0 arrived on August 17 with selective OCR packages across Rust, Python, Node.js, and the CLI. Open reports from the following week cover character decoding, hidden text, OCR confidence, and table structure, showing both active testing and unfinished edges.

PDF Inspector earns a serious trial for local extraction because its page routing is practical and its APIs span common runtimes. The measured 100-of-101 result is encouraging without being a clean pass. Use it behind explicit error handling, keep encrypted files out of the success path, and judge extracted content against real rendered pages before any system treats the Markdown as authoritative.

Alternatives

ProjectWhat it isPick it when
PyMuPDFPython bindings for inspecting, extracting, rendering, and modifying PDFs and other documents.pick this instead when page rendering and document manipulation matter as much as Markdown extraction.
pypdfA pure-Python library for reading, splitting, merging, cropping, and transforming PDFs.pick this instead when pure Python and structural PDF edits matter more than layout-aware Markdown.
MarkItDown gh↗A Python converter that turns PDFs and several office formats into Markdown.pick this instead when one interface for many document types matters more than PDF-specific routing.
OpenDataLoader PDFA PDF parser aimed at structured, accessible, AI-ready document output.pick this instead when document accessibility and a broader parser pipeline lead the requirements.

What people are saying

  1. [github-trending] firecrawl/pdf-inspector

Sources

  1. PDF Inspector repository and README
  2. PDF Inspector v1.15.0 release
  3. OCR routing guide request
  4. Type0 font decoding report
  5. Hidden text extraction report
  6. Numeric table-column report

More data reviews

zenoh · fonts · cockroach · dbt · GeoLibre · TradingView-API · the whole board →