pdf-inspector has a useful idea: inspect a PDF locally, extract native text when it is trustworthy, and send only the pages that need it to OCR. That can make private document pipelines cheaper and easier to audit than sending every file to a cloud parser.
The production verdict on August 10, 2026 is narrower than the project's sudden popularity suggests. Pilot it on trusted, representative documents, but do not put the currently published packages directly behind an untrusted upload endpoint. The repository is active and its default branch contains important parser and denial-of-service fixes, yet every stable registry artifact we found was published before at least some of those changes.
This is a researched technical analysis, not a hands-on benchmark. OpenSourceChoice inspected the repository, package registries, release history, security policy, recent pull requests, issues, and the project's published benchmark methodology. We did not execute the parser against a private corpus or independently reproduce its performance claims.
Executive verdict
| Question | OpenSourceChoice assessment |
|---|---|
| Best fit | Local routing and Markdown extraction for mostly native-text PDFs from trusted or controlled sources |
| Poor fit today | Public upload APIs, adversarial multi-tenant ingestion, or multilingual pipelines where right-to-left fidelity is mandatory |
| Real adoption cost | Sandboxed workers, resource limits, corpus QA, OCR fallback, monitoring, and package-release tracking—not the MIT license |
| Main risk | The published Rust, Python, Node, and browser packages predate recent fixes already merged into the repository |
| Parallel alternative | Evaluate Docling for harder layouts and OCR; use OCRmyPDF as a preprocessing companion for scanned documents |
| Production gate | Wait for a versioned release that includes the recent security and parser fixes, then verify it against your own malformed and multilingual corpus |
Why this matters now
The project is not new this week. Firecrawl introduced its PDF engine in April 2026, and the repository was created in February. The new event is adoption attention: on August 10, firecrawl/pdf-inspector ranked first on GitHub's weekly Trending page, where GitHub displayed 8,641 stars gained that week. A separate recent Reddit discussion focused on the local-processing and OCR-detection angle. Those are two independent discovery signals, but neither proves production quality.
The stronger reason to analyze it now is the collision between that attention and the release state. The repository was receiving maintainer commits and external pull requests through August 10, including security hardening, panic prevention, text extraction, table detection, and right-to-left work. At the same time, the project's public packages remained on versions built before several merged fixes.
Searches of Hacker News, Lobsters, XDA, and Product Hunt did not reveal an equally strong, project-specific current signal. That absence matters: this is a fast GitHub-led adoption wave with some community discussion, not a broad consensus across every developer channel.
The version number depends on your ecosystem
pdf-inspector does not have one synchronized public version. As observed on August 10, 2026:
| Distribution | Latest stable version | Published | What it means |
|---|---|---|---|
| Rust crate | 0.1.7 | July 31, 2026 | Native library and CLI source; depends on lopdf 0.41 in the published crate metadata |
| Python | 0.2.6 | July 31, 2026 | Wheels for major desktop/server targets plus source distribution |
| Node.js | 1.12.0 | August 3, 2026 | Native binaries for common Linux, macOS, and Windows targets |
| Browser WASM | 0.1.3 | July 31, 2026 | Local browser execution with a single-threaded runtime |
There are no GitHub Releases or signed release notes that unify these streams. The package registries are therefore the practical release record, while repository main represents newer, unreleased code. That distinction should be explicit in every architecture review and software bill of materials.
The Node package is a particularly clear example. npm records 1.12.0 as published on August 3 before the pull request that upgraded the vulnerable PDF dependency was merged later that day. The current repository manifests retain the same public package versions even though their source now points at the patched dependency.
What pdf-inspector actually does
The core is a Rust library built around lopdf. It parses a document once, classifies each page, extracts content from native PDF operators, and assembles a structured representation. Python uses PyO3 bindings, Node uses napi-rs, and browsers use WebAssembly.
The processing path is roughly:
- Load the PDF object graph and page resources.
- Inspect content streams for text and image operators.
- Classify pages as text-native, image-heavy, or likely scanned.
- Decode fonts, text positions, XObjects, links, and drawing commands.
- Reconstruct reading order, headings, lists, and tables.
- Emit Markdown or structured data and mark pages that should go to OCR.
This architecture has two attractive properties. First, local execution can keep PDF bytes inside your process boundary. Second, page-level routing can avoid paying the latency and compute cost of OCR on every page.
It is important not to overstate the scope. pdf-inspector does not provide its own OCR model, hosted queue, durable storage, access control, malware isolation, human review workflow, or quality SLA. Image-only pages need a separate OCR engine or service. The library can help decide where that fallback is needed; it does not replace it.
Browser WASM also changes the operational envelope rather than eliminating it. Local browser parsing can be useful for privacy-sensitive tools, but the project documents a single-threaded WASM runtime and recommends a Web Worker for large files. A worker protects interface responsiveness; it is not a complete security sandbox for hostile documents.
The benchmark is promising, not independent proof
The project publishes a reproducible benchmark over 200 PDFs from opendataloader-bench. Its July 31 results report an overall score of 0.875, with 0.915 for reading order, 0.814 for tables, and 0.788 for headings. The same table reports 0.470 seconds for all 200 documents on an Apple M4 Pro.
Those numbers are useful for forming a shortlist, with three qualifications:
- They are maintained and published by the project, not independently verified by OpenSourceChoice.
- OCR was disabled, so the test does not represent scanned-document completion or OCR cost.
- The corpus and scoring dimensions cannot predict performance on your invoices, filings, scientific papers, forms, or multilingual documents.
The methodology is better than an unexplained marketing chart: it names the dataset, competitor versions, hardware, warm-up behavior, and median-of-five procedure, and links to results that can be reproduced. Treat it as a candidate-selection benchmark. Your adoption decision still needs a frozen internal corpus and field-level acceptance criteria.
The release gap is the production blocker
The most consequential dependency is lopdf, the Rust parser that reads the underlying object graph. RustSec advisory RUSTSEC-2026-0187 covers lopdf versions through 0.41.0: a small, deeply nested crafted PDF can trigger a stack overflow and abort the process. The advisory assigns a high availability impact and lists 0.42.0 as the patched version.
pdf-inspector merged pull request #198 on August 3 to move from lopdf 0.41 to 0.42. However, the stable Rust crate remains 0.1.7, whose registry dependency metadata still resolves to the affected series. Issue #310, opened August 8, asks maintainers for a patch release specifically because ordinary parsing entry points can reach that dependency when handling third-party files.
The dependency bump is not the only unreleased hardening:
- Pull request #314, merged August 9, adds cycle detection, nesting limits, and a traversal budget for crafted AcroForm field graphs that could otherwise cause stack exhaustion or excessive CPU and memory use.
- Pull requests #320 and #321, also merged August 9, replace unchecked UTF-8 slicing paths that could panic on malformed or non-ASCII mapping and glyph names.
All four public package versions in the table above were published before the August 9 fixes. The result is not evidence that every input will fail, nor that a known exploit affects every binding identically. It is enough to reject the convenient assumption that installing the latest registry version gives you all fixes visible on main.
Building an audited commit from main can be reasonable in an isolated staging experiment, but it creates your own release and provenance burden. It also mixes security fixes with newer parser behavior. For production, a versioned upstream release with traceable package contents is the cleaner gate.
Correctness risks remain separate from security
Resource isolation does not tell you whether extracted text is complete. Open issues show why a domain corpus is mandatory:
- Issue #325 reports that
0.1.7extracts substantially less text than0.1.6from pages in a normal arXiv paper. This is a reporter's measurement, not an OpenSourceChoice reproduction, but it is a useful regression case. - Issue #327 reports reversed Arabic right-to-left output.
- Issue #332 reports extra spaces between Hebrew characters.
These are normal signs of a young parser confronting PDF complexity, not a reason to dismiss the project. They are also incompatible with a procurement claim such as “supports PDFs” without a more precise definition. Text presence, reading order, table structure, Unicode fidelity, and document completeness are different acceptance tests.
A safe deployment shape
Even after a patched release, treat every external PDF as hostile structured input. Do not parse it inside an API process that also owns credentials, sessions, or long-lived tenant state.
A defensible pipeline has these boundaries:
- Accept uploads into quarantine with a strict byte limit and content-type checks that do not rely only on the filename.
- Queue a job containing an opaque object reference, not raw bytes embedded in a message.
- Parse in a disposable worker with no secrets, no outbound network access, read-only code, and an empty writable scratch directory.
- Apply wall-clock, CPU, memory, page-count, decompression, and output-size limits.
- Route scan-like pages to a separately governed OCR stage.
- Validate the structured output before it reaches search, retrieval, or an LLM context.
- Store the package version, parser result, fallback path, timings, and termination reason for every job.
Containers help with packaging and resource controls, but a container alone is not a complete trust boundary. Use the isolation primitives appropriate to your platform, keep the worker unprivileged, and assume it will be terminated. A process abort should fail one document, not the ingestion service.
For browser-only use, parse in a dedicated Web Worker, cap file and page sizes before dispatch, provide cancellation, and avoid silently uploading failures to a cloud fallback. A privacy claim is only true if the fallback path is equally explicit.
Privacy, cost, and lock-in
The software is MIT-licensed, so there is no license fee and commercial use is permitted. That does not make the system operationally free.
The recurring cost is composed of:
- CPU and memory for native parsing;
- isolated worker capacity and queue management;
- OCR compute for scanned or low-confidence pages;
- storage for originals, outputs, and quarantine;
- regression-corpus maintenance and failure review;
- engineering time to follow asynchronous package versions and security advisories.
Local native or WASM parsing can keep document content under your control. Sending selected pages to an external OCR provider changes that data boundary and may introduce retention, residency, and per-page pricing. A fully local OCR engine avoids the provider dependency but adds model distribution, compute, and quality tuning.
Data lock-in is relatively low because the inputs are PDFs and the primary output is Markdown or structured text. Integration lock-in is moderate: page classifications, confidence rules, Markdown conventions, and error behavior become part of your application. Preserve originals and a parser-neutral intermediate record so you can reprocess with another engine.
Maturity and maintainer concentration
The project is active rather than abandoned. Its repository showed commits through August 10 and a busy pull-request queue spanning extraction, tables, bindings, packaging, and right-to-left work. It also has a current security policy that directs vulnerability reports to Bugcrowd or a private email channel.
The same evidence points to early-stage operational maturity:
- there is no GitHub release series or consolidated changelog;
- binding versions are not synchronized;
- important fixes can exist on
mainwithout a registry release; - issue reports still cover common extraction and internationalization cases;
- public contributor statistics show most historical commits concentrated in one maintainer account, even though recent contributions are broader.
That last point is a bus-factor warning, not a precise bus-factor score. Confirm release authority, succession, response expectations, and funding before making the parser a hard dependency in a regulated or high-volume service.
Alternatives to evaluate in parallel
No single alternative has exactly the same lightweight routing goal.
| Option | Evaluate it when | Main trade-off |
|---|---|---|
| Docling | You need richer document understanding, OCR, tables, and more formats | Heavier runtime and model footprint |
| MarkItDown | You want a simple multi-format conversion baseline | Less specialized control over PDF routing and layout |
| OCRmyPDF | Scanned PDFs need a searchable text layer before extraction | It is a preprocessing companion, not a complete structure extractor |
| PyMuPDF4LLM | You need mature PDF rendering/extraction features and can accept its licensing model | AGPL or commercial licensing requires an explicit legal decision |
For a mostly native-text corpus, benchmark pdf-inspector against MarkItDown and PyMuPDF4LLM. For mixed scans and complex tables, add Docling. OCRmyPDF is often better framed as a normalization stage that can feed more than one extractor.
A measurable evaluation plan
Do not begin with a public endpoint. Begin with a two-week offline gate:
1. Freeze versions and provenance
Record exact registry versions, package hashes, dependency trees, build platform, and the repository commit used for any custom build. Reject an unversioned “latest main” deployment.
2. Build a representative corpus
Sample at least the document families you actually ingest: born-digital text, scans, mixed pages, tables, forms, multi-column layouts, large files, encrypted files, damaged files, and every required language. Keep expected text and key fields for a reviewed subset.
3. Define quality thresholds
Measure page completion, character or token recall, reading-order accuracy, critical-field accuracy, table-cell fidelity, false OCR routing, and human-review rate. A single average score should not hide catastrophic failures in one document class.
4. Add adversarial cases
Include deeply nested objects, cyclic form fields, malformed character maps, decompression bombs, oversized images, extreme page counts, and the public regression files attached to relevant issues. Run them only inside the disposable worker boundary.
5. Measure operations
Capture p50 and p95 latency, peak memory, worker termination rate, queue delay, OCR percentage, OCR cost per 1,000 pages, and operator minutes per 1,000 documents.
6. Test failure behavior
Verify that timeouts, memory limits, parser aborts, corrupt output, and OCR failures affect one job; do not leak data; produce a diagnosable reason; and can be retried or quarantined without duplication.
7. Make the release gate explicit
Before production, require a published package that includes lopdf 0.42 or later plus the AcroForm and UTF-8 hardening merged on August 9. Re-run dependency advisories and the entire corpus against the exact candidate artifacts. If the project publishes different versions for each binding, verify each one separately.
Adopt only if the candidate meets your quality thresholds, adversarial documents remain contained, and its total cost beats the alternative on your own traffic. Reject or delay if a required language or document class misses its floor, if package provenance is unclear, or if release lag cannot fit your security process.
OpenSourceChoice conclusion
pdf-inspector is worth a controlled evaluation because page-level OCR routing, native performance, local execution, and portable output solve a real problem. The project also publishes enough benchmark detail to justify testing rather than relying on a demo.
It is not yet a responsible drop-in parser for untrusted production uploads. The decisive issue is not that the repository lacks fixes; it is that the fixes and the versions users can install are out of step. Sudden GitHub attention makes that distinction more important, not less.
For internal, trusted, mostly native-text documents, run a pinned offline pilot now. For public or multi-tenant ingestion, wait for patched versioned artifacts and keep the parser in disposable, resource-limited workers even after they arrive. Evaluate Docling in parallel for complex and scanned material, and keep OCRmyPDF available as a preprocessing option.
Sources
Sources were accessed on August 10, 2026 unless another date is listed.
- pdf-inspector repository, README, architecture, installation, license, and benchmark methodology — Firecrawl; repository state and
maindocumentation observed August 10, 2026. - Firecrawl PDF launch — Firecrawl; published April 14, 2026; used to distinguish the original launch from the August adoption signal.
- GitHub Trending — GitHub; weekly ranking and dynamic star-growth label observed August 10, 2026.
- Recent community discussion of pdf-inspector — Reddit; discovery and interest signal only, not technical evidence.
- Rust crate
pdf-inspector— crates.io; version0.1.7, published July 31, 2026. - Python package
pdf-inspector— Python Package Index; version0.2.6, files published July 31, 2026. - Node package
@firecrawl/pdf-inspector— npm; version1.12.0, published August 3, 2026. - Browser package
@firecrawl/pdf-inspector-wasm— npm; version0.1.3, published July 31, 2026. - RUSTSEC-2026-0187: stack overflow in
lopdf— RustSec Advisory Database; advisory dated June 21, 2026; affected versions through0.41.0, patched in0.42.0. - Pull request #198: upgrade
lopdfto 0.42 — pdf-inspector maintainers; merged August 3, 2026. - Issue #310: request for a security patch release — pdf-inspector issue tracker; opened August 8, 2026; reporter evidence about the published Rust crate.
- Pull request #314: bounded AcroForm traversal — pdf-inspector maintainers; merged August 9, 2026.
- Pull request #320: checked ToUnicode slicing and pull request #321: checked glyph-name slicing — pdf-inspector maintainers; merged August 9, 2026.
- Issue #325: reported text-extraction regression, issue #327: Arabic RTL output, and issue #332: Hebrew spacing — pdf-inspector issue tracker; opened August 9–10, 2026; community reports, not independently reproduced here.
- Security policy — Firecrawl; current reporting scope and channels.
- Docling, MarkItDown, OCRmyPDF, and PyMuPDF4LLM — official repositories; current capabilities and licenses checked for the alternatives section.
Build a stack for this use case.
Answer nine practical questions and compare three transparent architectures with costs, free limits, lock-in, and migration paths.
Build my stack


