Introducing the New PyMuPDF4LLM: Now Including Layout
Kayla Klein·March 16, 2026

Since we released Layout last November, a PDF native Graph Neural Network for document layout analysis, we've kept working on improvements.
Single install
In a recent user survey, the most consistent piece of feedback we heard was around the friction of managing two separate packages. PyMuPDF4LLM and PyMuPDF-Layout had to be installed separately, version mismatches caused issues, and frankly, it was more setup than was necessary. With this release, installing pymupdf4llm will automatically install the specific required version of pymupdf_layout, and import pymupdf4llm will automatically activate Layout. One install, one import, Layout activates automatically.
pip install pymupdf4llmimport pymupdf4llm
md = pymupdf4llm.to_markdown("document.pdf")No configuration needed.
F1 improvement
For those unfamiliar with the metric: F1 score is the standard way to measure detection quality in machine learning. It combines precision (are the detections correct?) and recall (did we find everything?) into a single number. You need both, because if one is high but the other is low, F1 will reflect that. You can't game it by optimizing only one side.
Our overall F1 improved from 0.8343 to 0.8640, approximately a 3.6% gain over the November release. The biggest jumps were in small region elements: page footer detection alone went from 0.7493 to 0.8913, roughly a 19% improvement. Section headers, page headers, and titles also improved noticeably. We will continue to improve the F1 score going forward.
OCR support
PyMuPDF4LLM now has a plugin-based OCR pipeline. Tesseract, RapidOCR, and PaddleOCR (good at CJK languages) are supported out of the box: if any of these are installed, pages requiring OCR are automatically detected and processed before Layout kicks in.
If you use a different engine, pass a custom function via ocr_function:
md = pymupdf4llm.to_markdown("scanned.pdf", ocr_function=my_ocr_engine)If a page needs OCR it is passed to my_ocr_engine together with its image to receive a text layer. Then the rest of the pipeline continues as usual.
Curious how the output looks? Try the live demo with our sample documents, and let us know what you think.