Blog

pdfplumber vs PyMuPDF vs pypdf: Python PDF text extraction compared

Published July 14, 2026 · Read as Markdown

For extracting text from PDFs in Python, the choice is usually between three libraries: pypdf (pure Python, simplest), PyMuPDF (fastest, richest features, AGPL-licensed), and pdfplumber (best table introspection, built on pdfminer). All three read the text layer only — none of them does OCR — and each earns its place depending on what you’re extracting and where the code runs.

The three at a glance

pypdfPyMuPDF (fitz)pdfplumber
ImplementationPure PythonC (MuPDF) bindingsPure Python (pdfminer.six)
SpeedModerateFastest by a wide marginSlowest
Table extractionNoBasic (find_tables)Best-in-class (extract_tables)
Markdown outputNoVia pymupdf4llm add-onNo
Layout/geometry accessLimitedFullFull, very ergonomic
LicenseBSDAGPL-3.0 (or paid commercial)MIT
Install weightLightBinary wheelLight

When to pick each

Pick pypdf for simple jobs in constrained environments: page counts, merging/splitting, plain text where layout doesn’t matter. Pure Python means it runs anywhere, and BSD licensing raises no questions.

Pick PyMuPDF when speed matters or you want Markdown: it’s routinely an order of magnitude faster than the pure-Python options, and the pymupdf4llm companion package outputs LLM-ready Markdown with headings and tables. The catch is licensing — AGPL-3.0 obliges you to open-source network-served code that uses it, unless you buy a commercial license. Many companies discover this after shipping.

Pick pdfplumber when tables are the job: its extract_tables() with tunable strategies (ruling lines vs whitespace alignment) plus visual debugging (page.to_image().debug_tablefinder()) is the best table tooling in Python. MIT-licensed. Accept that it’s the slowest of the three.

The code, side by side

# pypdf — plain text
from pypdf import PdfReader
text = "\n".join(p.extract_text() or "" for p in PdfReader("doc.pdf").pages)

# PyMuPDF — Markdown via pymupdf4llm
import pymupdf4llm
md = pymupdf4llm.to_markdown("doc.pdf")

# pdfplumber — tables
import pdfplumber
with pdfplumber.open("doc.pdf") as pdf:
    tables = [t for page in pdf.pages for t in page.extract_tables()]

The fourth option: don’t install anything

If what you need is clean Markdown out of a text-layer PDF, the library route means owning a dependency, its upgrades, and (for PyMuPDF) a licensing question — to reimplement what one HTTP call does:

import requests

with open("doc.pdf", "rb") as f:
    md = requests.post(
        "https://api.marklipi.com/convert", files={"file": f}, timeout=60
    ).json()["markdown"]

No API key, free tier of 100 conversions/day, deterministic output, nothing stored. Libraries win when files can’t leave your machine or you need cell-level geometry; the API wins on zero setup and no license text to read. (Where each tool on the wider market fits.)

FAQ

Which Python PDF library is fastest?

PyMuPDF, and it isn’t close — its MuPDF C core typically processes pages an order of magnitude faster than pypdf or pdfplumber on the same corpus.

Which extracts tables best?

pdfplumber, thanks to configurable detection strategies and visual debugging. PyMuPDF’s find_tables is serviceable; pypdf doesn’t do tables.

None of these work on my scanned PDF. Why?

All three read the embedded text layer, and a scan doesn’t have one. You need OCR (e.g., Tesseract, Marker, Docling) for scans — here’s how to tell which you’re dealing with.

Is PyMuPDF free for commercial use?

It’s AGPL-3.0: free if you comply with AGPL’s obligations (including for network services), otherwise Artifex sells commercial licenses. Evaluate with your counsel — many teams choose pdfplumber (MIT) or an API to sidestep the question.

Try it on a real PDF.

Free in-browser converter, no signup — or one curl to the API.