PDF to Markdown in Python

Four libraries that turn PDFs into Markdown, with the install command and working code for each, what their licences allow, and how to choose between them.

Last updated: 2026-11-13

Which library to pick

LibraryLicenceNeedsBest for
PyMuPDF4LLMAGPL 3.0, or a paid commercial licenceNothing beyond pipFast, accurate text PDFs; headings and tables
MarkItDownMITNothing beyond pipMany file types through one call
DoclingMITPyTorch, model downloadsComplex layouts, tables, structured output
MarkerApache 2.0 code; model weights under a modified OpenRAIL-M licencePyTorch, and an inference server for OCRFormula-heavy papers and scans, ideally with a GPU

The versions below were current on the date at the top of this page. If you only have a handful of PDFs, you don't need any of them: the converter on our home page does the same in your browser.

PyMuPDF4LLM

PyMuPDF's Markdown export. Since PyMuPDF 2.0 it ships inside the pymupdf package; the import name stays pymupdf4llm.

pip install pymupdf
import pymupdf4llm

md = pymupdf4llm.to_markdown("report.pdf")
open("report.md", "w", encoding="utf-8").write(md)

Useful options:

# Only some pages (0-based), as one dict per page with its metadata
pages = pymupdf4llm.to_markdown("report.pdf", pages=[0, 1, 2], page_chunks=True)
for p in pages:
    print(p["metadata"]["page_number"], len(p["text"]))

For scanned pages, install an OCR engine as well: with pip install rapidocr onnxruntime, PyMuPDF reads pages that have no text layer.

Licence: PyMuPDF is dual-licensed under the GNU AGPL 3.0 or a commercial licence from Artifex. The AGPL requires you to release your own source code if you distribute the software or offer it as a network service, so check this before using it in a closed product.

In our benchmark, PyMuPDF4LLM 2.1 kept 99% of the body text on average and had the best reading order of the three converters we scored.

MarkItDown

Microsoft's converter for many formats: PDF, Word, PowerPoint, Excel, HTML, EPUB and more.

pip install 'markitdown[pdf]'
from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("report.pdf")
open("report.md", "w", encoding="utf-8").write(result.markdown)

From the command line: markitdown report.pdf -o report.md.

Licence: MIT.

Good to know: for PDFs it extracts text with pdfminer.six and pdfplumber. The output has no headings, keeps the PDF's line breaks and end-of-line hyphens, and the default install has no OCR. It's the right pick when PDFs are a small part of a mixed pile of office files. Our MarkItDown page has the details.

Docling

A document conversion toolkit started at IBM Research Zurich and now hosted by the LF AI & Data Foundation. It runs layout, table and OCR models, so it installs PyTorch and downloads the models on first use. Besides PDF it reads Word, PowerPoint, Excel, HTML, images and more.

pip install docling
from docling.document_converter import DocumentConverter

converter = DocumentConverter()
result = converter.convert("report.pdf")
md = result.document.export_to_markdown()
open("report.md", "w", encoding="utf-8").write(md)

From the command line: docling report.pdf writes a .md file in the current folder.

Licence: MIT. Besides Markdown, the document exports to HTML and to a lossless JSON format that keeps the layout information for later processing.

Marker

Datalab's converter, built around its own vision models. It's strong on formulas and scans, and heavier to run.

pip install marker-pdf

Marker needs PyTorch, and for OCR it starts an inference server on first use: vLLM on an NVIDIA GPU, or the llama-server binary from llama.cpp on a CPU or Apple Silicon.

from marker.converters.pdf import PdfConverter
from marker.models import create_model_dict
from marker.output import text_from_rendered

converter = PdfConverter(artifact_dict=create_model_dict())
rendered = converter("report.pdf")
text, _, images = text_from_rendered(rendered)
open("report.md", "w", encoding="utf-8").write(text)

From the command line: marker_single report.pdf.

Licence: the code is Apache 2.0. The model weights use a modified AI Pubs OpenRAIL-M licence, free for research, personal use and startups under $5M in funding or revenue; larger commercial use needs a licence from Datalab.

Convert a folder of PDFs

The same loop works with any of the libraries; here with PyMuPDF4LLM:

from pathlib import Path
import pymupdf4llm

src, out = Path("pdfs"), Path("markdown")
out.mkdir(exist_ok=True)
for pdf in sorted(src.glob("*.pdf")):
    try:
        md = pymupdf4llm.to_markdown(str(pdf))
    except Exception as e:  # a damaged or encrypted file shouldn't stop the batch
        print(f"skipped {pdf.name}: {e}")
        continue
    (out / f"{pdf.stem}.md").write_text(md, encoding="utf-8")

When a script is the wrong tool

  • A few files, once: dropping them on the converter is quicker than setting up an environment, and you can check each page against its Markdown.
  • Sensitive documents on a shared machine: the browser converter needs no install and keeps the file in the tab.
  • You want token counts and RAG chunks without writing them yourself: see PDF to Markdown for LLMs.

Frequently asked questions

Which library is fastest?

On text PDFs, MarkItDown and PyMuPDF4LLM take a fraction of a second to a few seconds per document on a laptop. Docling and Marker run neural models and are much slower without a GPU.

Which one handles tables best?

Of the two we measured, PyMuPDF4LLM produced proper Markdown tables, and MarkItDown mostly didn't. Docling and Marker both use table models and are often recommended for complex tables; test them on your own documents.

Can I use these in a commercial product?

MarkItDown and Docling are MIT, which allows it. PyMuPDF needs either AGPL compliance or a commercial licence. Marker's code is Apache 2.0, but its model weights have revenue limits for commercial use.

Is there a JavaScript option?

pdftomd itself runs in JavaScript and WebAssembly in the browser. Its text engine is the open-source @firecrawl/pdf-inspector-wasm package, and its OCR is PaddleOCR running on ONNX Runtime Web. See the licences page for every component.