Skip to main content

FibrumPDF

Structured PDF extraction at 318 pages per second on CPU.

Python 3.11+ CI License: AGPL-3.0

FibrumPDF turns digital PDFs into structured JSON or clean Markdown without a GPU, a model download, or a remote API. It preserves headings, paragraphs, lists, tables, reading order, bounding boxes, links, and inline formatting while keeping extraction native and parallel.

The native pipeline targets workloads that need structure without spending seconds on every page.

Benchmark dashboard

Performance, measured

The repository benchmark contains 512 documents from the datalab-to/marker_benchmark dataset. On the documented Ryzen 7 4800H test system, the current FibrumPDF build processes 318.2 pages/s, about 77x PyMuPDF4LLM and 517x Docling in this benchmark.

Extractor Pages/s Text score Table TEDS Table precision Table recall
FibrumPDF 318.23 87.31 0.783 0.661 0.590
PyMuPDF4LLM 4.15 86.54 0.778 0.647 0.554
Docling 0.62 91.13 0.821 0.796 0.738

PyMuPDF4LLM is the closest speed comparison. Docling scores higher on difficult tables and irregular layouts, but takes substantially longer.

Open the interactive report or see how the benchmark works.

Features

  • Semantic blocks: headings, paragraphs, lists, code, figures, and tables.
  • Layout metadata: page numbers and block, row, cell, and span bounding boxes.
  • Inline formatting: bold, italic, monospace, strikeout, super/subscript, links.
  • Two consumption modes: collect small documents or stream large ones page by page with bounded memory.
  • Atomic output: failed extraction never leaves a half-written destination.
  • Native wheels for Python 3.11+ on Linux x86_64, macOS arm64, and Windows x64.

Quick start

uv pip install fibrum-pdf

Extract JSON:

from fibrum_pdf import to_json

result = to_json("report.pdf", "report.json")
print(result.path)

for page in result:  # streamed; the whole document is not loaded
    print(page.markdown)

Write Markdown directly. Pages are converted incrementally and the destination is replaced atomically:

from fibrum_pdf import to_markdown

path = to_markdown("report.pdf", "report.md")

For smaller documents, collect typed Pydantic-backed objects:

pages = to_json("report.pdf").collect()

print(pages[0].markdown)
print(pages[0][0].type, pages[0][0].bbox)

The CLI exposes both formats:

uv run fibrum-pdf report.pdf report.json
uv run fibrum-pdf report.pdf report.md --format markdown

The output path is optional; it defaults to the PDF name with a .json or .md suffix.

Output model

The JSON document is an array of pages. Each page contains a data array of blocks:

[
  {
    "page": 1,
    "data": [
      {
        "type": "heading",
        "level": 1,
        "bbox": [178.64, 84.50, 433.36, 102.55],
        "font_size": 24,
        "spans": [
          {"text": "Quarterly report", "font_size": 0, "bold": true}
        ]
      }
    ]
  }
]

Tables add row and cell geometry; lists add typed items, markers, and indentation. See the public models for the complete schema.

How it works

MuPDF handles PDF interpretation. Go performs layout analysis, table detection, classification, cleanup, and bounded parallel page processing. Python stays a thin orchestration layer and exposes the native result lazily through ijson.

Text and vector edges are captured in one page pass. Ruled tables use line grids. Borderless tables are built from contiguous multi-column rows, with structural checks to reject prose columns, diagrams, and fragmented labels.

MuPDF access is serialized where required. Page processing uses bounded workers, so memory use depends on active pages rather than document length.

Known limits

FibrumPDF does not run OCR or extract embedded images. Scanned PDFs require another tool. Forms, spreadsheets, heavily layered pages, and unconventional visual layouts can also defeat the heuristic extractor.

Use the benchmark as a starting point, then test representative documents from your own workload before committing to an extraction stack.

Reproduce the benchmark

Benchmark reports are generated by the code in benchmark/. The committed comparison uses 512 deterministic samples (--seed 0, one timing run) on an AMD Ryzen 7 4800H; Docling used the machine's GTX 1650 Ti where applicable.

uv sync --extra benchmark
uv run python -m benchmark download \
  --output benchmark/data --max-rows 512
uv run python -m benchmark run \
  --dataset-path benchmark/data \
  --output benchmark/results \
  --max-rows 512 --runs 1

Per-document measurements, aggregate rows, and generated reports are committed under benchmark/results/. Throughput varies by hardware; the quality scores are the more portable comparison.

Development

Source builds require MuPDF 1.27. See BUILD.md for platform setup. Once the native dependency is available:

uv sync --extra dev
uv run ruff check .
uv run ruff format --check .
uv run pytest -q

cd go
go test ./...
go vet ./...

License

FibrumPDF is licensed under AGPL-3.0. MuPDF is also AGPL-licensed and is available under a commercial license from Artifex.

Metadata

Release files for fibrum-pdf 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for fibrum-pdf 1.2.0
File Interpreter ABI Platform
fibrum_pdf-1.2.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 Details
fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl Python 3 none macOS 15.0+ ARM64 Details

Total release size: 201.4 MB

Release files / fibrum_pdf-1.2.0-py3-none-win_amd64.whl

Download URL fibrum_pdf-1.2.0-py3-none-win_amd64.whl
Size 41.1 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
002fabcdcff3524810f79160aa5eb2d544f1cfa743a701dcc50113bbc7bbea9a
BLAKE2b-256 checksum
How to use checksums
6b37648b17dfbb55d109906e7c25c2c2b9505c2c43ba693b3266b1cc5723ec5e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 18, 2026.

Transparency log

Release files / fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 79.7 MB
Tags Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
89da40f6ed51c248383813b37f23aab66c325578f0f18e04428f55f93ee6cd2e
BLAKE2b-256 checksum
How to use checksums
2f1bff11d00deedb319a42082ed98edca4ad090d6822e93be788cedc49073b14
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 18, 2026.

Transparency log

Release files / fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl

Download URL fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl
Size 80.6 MB
Tags Python 3 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
9c498b2ae5604efb4bd5ce22f21878dbf78efce47168a27867ee3ef090c67e3c
BLAKE2b-256 checksum
How to use checksums
fe010311e42b2bbf3cb6b25d4934540973604005ed235721ac95dd249d718fb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

3 release files

1.1.2

12 release files

1.1.1

13 release files

1.1.0

12 release files

1.0.3

12 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page