mrkeyoor.com_
Sat 08 Aug 21:01 UTC
PyPIDataupdated 08 Aug 2026

pymupdf4llm

PyMuPDF4LLM turns PDFs and other MuPDF-readable documents into Markdown, plain text, or layout-rich JSON for search and retrieval pipelines. Version 1.28.2 automatically activates the separately packaged PyMuPDF Layout model to infer reading order, headings, lists, tables, pictures, and page regions, then selectively calls an installed OCR engine for pages or spans with unusable text. It can also return per-page chunks, save or embed images, extract PDF form values, and feed LlamaIndex.

Verdict

PyMuPDF4LLM is a capable local extractor, but it is neither lightweight nor license-neutral after the automatic Layout dependency. Install it when its document quality wins on your own corpus and both licensing layers are acceptable; otherwise start with pypdf or compare Docling and Unstructured.

API stability3/5The familiar to_markdown entry point remains, but the package recently changed versioning, made PyMuPDF Layout automatic, pins exact dependency versions, and changes available APIs when global layout mode is toggled. The changelog documents evolving page-chunk schemas, OCR modes, defaults, table behavior, and many new keyword arguments. Callers should pin versions and test outputs rather than assume equivalent results across minor-looking releases.
Docs4/5The README and live documentation cover output formats, OCR triggers, image handling, page chunks, tables, supported formats, LlamaIndex and LangChain paths, selective pages, form data, and licensing. There are useful warnings about forced OCR and Office support. Precision is uneven: current source defaults ocr_dpi to 150 in layout functions while README prose says 300, to_json's string return is easy to miss, and the repository changelog does not yet headline 1.28.2.
Maintenance5/5Version 1.28.2 was published on 2026-08-06 and the repository was pushed on 2026-08-07. GitHub reports 38 open issues and pull requests, while the source includes active tests for OCR, malicious Markdown links, HTML tables, regressions, and LlamaIndex. The pace is high and fixes are concrete, although that same pace makes output regression testing and exact dependency pins important for production users.
Ecosystem4/5The package records 5,474,647 weekly downloads and 2,075 GitHub stars, builds on the mature MuPDF engine, and documents direct LlamaIndex plus LangChain workflows. It handles PDF, XPS, EPUB-family formats, images, and paid Office extensions. Adoption is constrained by AGPL or commercial licensing, the separately licensed Layout package, exact PyMuPDF pairing, and optional external OCR engines and language data.

Use it if

  • You need local PDF-to-Markdown extraction with multi-column reading order, headings, tables, images, and optional OCR
  • Your retrieval pipeline benefits from per-page text plus source metadata and layout box character ranges
  • You want JSON coordinates and layout classes for a custom document-processing pipeline
  • You can accept the AGPL terms or purchase an Artifex commercial license and can also accept the separate PyMuPDF Layout licensing
Skip it if

Setup reality

pip install pymupdf4llm on Python 3.10 or newer now installs exact versions of pymupdf and pymupdf_layout plus tabulate and psutil. This is not a small pure-Python helper in practical terms: PyMuPDF wraps the native MuPDF engine, Layout uses its own model and dependencies, and the project changelog calls out packages such as onnxruntime, numpy, and sympy in that path. Check the separate Layout license as well as PyMuPDF4LLM's AGPL-or-commercial terms before deployment. Importing pymupdf4llm activates Layout globally and verifies that PyMuPDF's version exactly matches; pymupdf4llm.use_layout(False) switches process-global behavior to the legacy extractor, where to_json and to_text are unavailable and custom IdentifyHeaders becomes available. OCR does not become self-contained just because the Python package installed. Automatic selection can use Tesseract language data or rapidocr_onnxruntime when present; without a usable engine, normal extraction disables OCR with a warning, while forced OCR raises. Install and test the right language packs, and budget CPU and memory for image rendering and inference. The README's OCR default examples and current source defaults do not fully agree, so pass ocr_dpi explicitly when it matters. Page indexes are zero-based. to_json returns a JSON string, not a decoded dict. write_images needs a writable directory and cannot be combined with embed_images. Office files require the separate PyMuPDF Pro package and a commercial key for full functionality. Finally, extraction quality is heuristic: keep a representative fixture set with scanned, multi-column, table-heavy, rotated, and malformed files, then diff outputs during every version upgrade.

Patterns

Convert a document to Markdownconvert-to-markdown

from pathlib import Path
import pymupdf4llm

markdown = pymupdf4llm.to_markdown('report.pdf')
Path('report.md').write_text(markdown, encoding='utf-8')

Layout mode is activated automatically in 1.28.2. Treat generated Markdown as extracted data and inspect it before rendering it as trusted HTML.

Extract only selected pagesextract-selected-pages

import pymupdf4llm

markdown = pymupdf4llm.to_markdown(
    'report.pdf',
    pages=[0, 1, 5],
)

Page indexes are zero-based. Invalid or reordered page lists should be covered by your own tests when source-page mapping matters.

Return one metadata record per pagecreate-page-chunks

chunks = pymupdf4llm.to_markdown(
    'report.pdf',
    page_chunks=True,
)

for chunk in chunks:
    page = chunk['metadata']['page_number']
    text = chunk['text']
    boxes = chunk['page_boxes']
    index_page(page, text, boxes)

These are physical page chunks, not semantic chunks. Each page_boxes item includes a class, bounding box, and character slice into the chunk text.

Decode layout-rich JSON outputextract-layout-json

import json
import pymupdf4llm

json_text = pymupdf4llm.to_json('report.pdf', pages=[0, 1])
data = json.loads(json_text)

to_json returns a JSON string and is available only in Layout mode. Calling pymupdf4llm.use_layout(False) makes this API raise NotImplementedError.

Produce plain text with bounded tablesextract-plain-text

text = pymupdf4llm.to_text(
    'report.pdf',
    table_format='grid',
    table_max_width=100,
    table_min_col_width=10,
)

to_text is Layout-only. Table formatting uses tabulate conventions and does not guarantee the original document's visual alignment.

Write document images beside Markdownsave-extracted-images

from pathlib import Path
import pymupdf4llm

image_dir = Path('report-images')
image_dir.mkdir(parents=True, exist_ok=True)
markdown = pymupdf4llm.to_markdown(
    'report.pdf',
    write_images=True,
    image_path=str(image_dir),
    image_format='png',
    dpi=150,
)

The process needs write permission and extracted files need lifecycle management. Do not combine write_images=True with embed_images=True.

Embed images as data in Markdownembed-images

markdown = pymupdf4llm.to_markdown(
    'report.pdf',
    embed_images=True,
    dpi=120,
)

Embedding avoids sidecar files but can make Markdown very large. It is mutually exclusive with write_images in the current layout path.

Configure language-aware automatic OCRconfigure-selective-ocr

markdown = pymupdf4llm.to_markdown(
    'mixed-scan.pdf',
    use_ocr=True,
    force_ocr=False,
    ocr_language='eng+fra',
    ocr_dpi=200,
)

A compatible OCR engine and language data must already be installed. Pass ocr_dpi explicitly because current source and README defaults are not fully aligned.

Keep extraction native and predictabledisable-ocr

markdown = pymupdf4llm.to_markdown(
    'digital.pdf',
    use_ocr=False,
)

Image-only pages can return no text when OCR is disabled. This is useful when OCR latency or recognition errors are unacceptable.

Emit reconstructed HTML tablesrender-html-tables

markdown = pymupdf4llm.to_markdown(
    'tables.pdf',
    table_output='html',
    edge_threshold=0.75,
)

Only table output changes to HTML. Sanitize the result before inserting it into a web page if the source document is untrusted.

Read form field names and valuesextract-pdf-form-values

import pymupdf4llm

fields = pymupdf4llm.get_key_values('application.pdf', xrefs=True)
for name, value in fields.items():
    print(name, value)

Non-form PDFs return an empty dict. xrefs are low-level PDF object references useful for loading widgets through PyMuPDF.

Batch-convert a directory from the CLIconvert-directory-cli

pymupdf4llm documents/ --out extracted/ --backend md --pattern '*.pdf' --workers 2 --ocr-lang eng

The CLI writes per-document output directories and logs. Choose workers from measured memory use because Layout and OCR state can make each worker expensive.

Alternatives

PackageRegistryPick it when
doclingPyPIUse it for a broader document-conversion pipeline with structured document models and multiple parsing backends
unstructuredPyPIUse it when partitioning many file types and attaching normalized element metadata matters more than a compact PDF-focused API
pypdfPyPIUse it for lightweight PDF text and metadata access when you do not need layout inference, table reconstruction, or OCR orchestration