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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fibrum_pdf-1.2.0-py3-none-win_amd64.whl (41.1 MB view details)

Uploaded Python 3Windows x86-64

fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (79.7 MB view details)

Uploaded Python 3manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl (80.6 MB view details)

Uploaded Python 3macOS 15.0+ ARM64

File details

Details for the file fibrum_pdf-1.2.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: fibrum_pdf-1.2.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 41.1 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fibrum_pdf-1.2.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 002fabcdcff3524810f79160aa5eb2d544f1cfa743a701dcc50113bbc7bbea9a
MD5 3fd8fe83d8d64347aa3d8bf8a5dbcc85
BLAKE2b-256 6b37648b17dfbb55d109906e7c25c2c2b9505c2c43ba693b3266b1cc5723ec5e

See more details on using hashes here.

Provenance

The following attestation bundles were made for fibrum_pdf-1.2.0-py3-none-win_amd64.whl:

Publisher: publish.yml on intercepted16/fibrumpdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 89da40f6ed51c248383813b37f23aab66c325578f0f18e04428f55f93ee6cd2e
MD5 f8b558ba2d2adb1772d762001278bfb5
BLAKE2b-256 2f1bff11d00deedb319a42082ed98edca4ad090d6822e93be788cedc49073b14

See more details on using hashes here.

Provenance

The following attestation bundles were made for fibrum_pdf-1.2.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on intercepted16/fibrumpdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 9c498b2ae5604efb4bd5ce22f21878dbf78efce47168a27867ee3ef090c67e3c
MD5 7437fa4d6a9c131b70883199566a5b2a
BLAKE2b-256 fe010311e42b2bbf3cb6b25d4934540973604005ed235721ac95dd249d718fb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for fibrum_pdf-1.2.0-py3-none-macosx_15_0_arm64.whl:

Publisher: publish.yml on intercepted16/fibrumpdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page