Free to list, always.No paid rankings. Every recommendation explains its trade-offs.
OpenSourceChoice
Security

pdf-inspector Is Trending, but Its Packages Lag Security Fixes

pdf-inspector is fast and local, but its published packages lag key PDF security fixes. A practical production-readiness analysis.

Last reviewed
Evidence
3 official sources
pdf-inspectorpdf-parsingrustocrdocument-aisecurityself-hosting
pdf-inspector Is Trending, but Its Packages Lag Security Fixes

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

QuestionOpenSourceChoice assessment
Best fitLocal routing and Markdown extraction for mostly native-text PDFs from trusted or controlled sources
Poor fit todayPublic upload APIs, adversarial multi-tenant ingestion, or multilingual pipelines where right-to-left fidelity is mandatory
Real adoption costSandboxed workers, resource limits, corpus QA, OCR fallback, monitoring, and package-release tracking—not the MIT license
Main riskThe published Rust, Python, Node, and browser packages predate recent fixes already merged into the repository
Parallel alternativeEvaluate Docling for harder layouts and OCR; use OCRmyPDF as a preprocessing companion for scanned documents
Production gateWait 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:

DistributionLatest stable versionPublishedWhat it means
Rust crate0.1.7July 31, 2026Native library and CLI source; depends on lopdf 0.41 in the published crate metadata
Python0.2.6July 31, 2026Wheels for major desktop/server targets plus source distribution
Node.js1.12.0August 3, 2026Native binaries for common Linux, macOS, and Windows targets
Browser WASM0.1.3July 31, 2026Local 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:

  1. Load the PDF object graph and page resources.
  2. Inspect content streams for text and image operators.
  3. Classify pages as text-native, image-heavy, or likely scanned.
  4. Decode fonts, text positions, XObjects, links, and drawing commands.
  5. Reconstruct reading order, headings, lists, and tables.
  6. 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.7 extracts substantially less text than 0.1.6 from 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:

  1. Accept uploads into quarantine with a strict byte limit and content-type checks that do not rely only on the filename.
  2. Queue a job containing an opaque object reference, not raw bytes embedded in a message.
  3. Parse in a disposable worker with no secrets, no outbound network access, read-only code, and an empty writable scratch directory.
  4. Apply wall-clock, CPU, memory, page-count, decompression, and output-size limits.
  5. Route scan-like pages to a separately governed OCR stage.
  6. Validate the structured output before it reaches search, retrieval, or an LLM context.
  7. 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 main without 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.

OptionEvaluate it whenMain trade-off
DoclingYou need richer document understanding, OCR, tables, and more formatsHeavier runtime and model footprint
MarkItDownYou want a simple multi-format conversion baselineLess specialized control over PDF routing and layout
OCRmyPDFScanned PDFs need a searchable text layer before extractionIt is a preprocessing companion, not a complete structure extractor
PyMuPDF4LLMYou need mature PDF rendering/extraction features and can accept its licensing modelAGPL 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.

Turn research into an architecture

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