All comparisons
Comparison

PyMuPDF vs pypdf: a C rendering engine against a pure-Python page toolkit

These two solve different halves of the same problem. PyMuPDF wraps the MuPDF C engine and gives you page geometry, rendering, redaction and table detection; pypdf is pure Python and gives you page-level surgery, encryption and metadata without shipping a binary. Pick PyMuPDF when the page is an image you have to look at, and pypdf when the page is a range of indices you have to rearrange.

Published September 30, 2026

At a glance

Projectpymupdf/PyMuPDFpy-pdf/pypdf
LicenceAGPL-3.0Network copyleft: hosting a modified version means sharing sourceCustom licenceCustom licence: read the LICENSE file
MaintenanceCommits in the last six monthsLast push November 6, 2026Commits in the last dayLast push November 7, 2026
LanguagePythonPython
GitHub stars11,08510,291
Read moreOur analysisGitHubOur analysisGitHub

Star history

  • pymupdf/PyMuPDF11,085 ★ · +327
  • py-pdf/pypdf10,291 ★ · +70
Star history
Repository2026-09-222026-11-07
pymupdf/PyMuPDF10.8k11.1k
py-pdf/pypdf10.2k10.3k

Open the full Star history comparison

Which one to choose

PyMuPDF

Choose PyMuPDF if you need to see the page rather than just move it. It rasterises at any DPI, returns per-span font and size metadata, finds tables and converts them to Markdown or a Pandas DataFrame, renders vector output and produces bounding-box JSON, all from one binary with no mandatory dependencies. Choose it when your document is scanned, laid out in columns, or has to be redacted, and when your distribution model can live with AGPL-3.0.

pypdf

Choose pypdf if your work is splitting, merging, cropping, transforming, encrypting and reading metadata inside a Python process. It is pure Python, so nothing compiled has to reach your deployment target, and pip install pypdf[crypto] adds AES when you need it. Choose it when you ship closed-source software, when the job is assembling and splitting rather than interpreting, and when you would rather not own a C toolchain dependency.

A C rendering engine against a pure-Python page toolkit

PyMuPDF is a binding. The README says it is built on top of MuPDF, a lightweight, fast C engine, and that it gives precise, low-level control over documents alongside high-level convenience APIs with no mandatory external dependencies. Control is the operative word. Its object model is the page and everything on it: get_text for a flat string, get_text("dict") for blocks, lines and spans carrying font, size, colour and position, find_tables for detected tables, get_pixmap for a rasterised image at whatever DPI you ask for. Every one of those is a coordinate or a rectangle, and the value of the library is that you get to decide what to do with them.

pypdf is a document library. Its own description calls it a free and open-source pure-python library capable of splitting, merging, cropping and transforming the pages of PDF files, and it can also add custom data, viewing options and passwords, and retrieve text and metadata. The object model is the page tree and the writer, and the value of the library is that a page is a thing you can reorder, duplicate, drop, rotate into a different box and hand to a new file. It is the maintained successor to PyPDF2, so it inherits that community rather than a separate one.

The practical reading of the difference: one project is a renderer that also reads documents, the other is a surgeon that also reads documents. A scan of a contract, a page preview, a highlighted region and a redaction box all need the renderer's model. A mail-merge attachment, a 400-page split, a password on an export and a metadata cleanup do not.

Installation, and what ends up in your deployment

PyMuPDF installs with pip install pymupdf, and pre-built wheels are published for Windows, macOS and Linux on Python 3.10 to 3.14. The README also states what happens when no wheel matches: pip compiles from source, which requires a C and C++ toolchain. That is the whole installation story for the core library, and it has one consequence worth planning for. A compiled artefact has to exist for your exact platform and interpreter, and where it does not, somebody needs a compiler on the build machine. Interpreter versions outside 3.10 to 3.14 fall into that case.

The features a product often needs are separate installs rather than extras of the core: pymupdf-fonts for an extended font collection in text output, pymupdf4llm for Markdown and JSON extraction aimed at retrieval and AI pipelines, pymupdfpro for Microsoft Office and Korean Office formats, and tesseract-ocr for scanned pages and images. OCR has a further step outside Python, since Tesseract itself has to be installed on the machine with brew install tesseract on macOS or sudo apt install tesseract-ocr on Ubuntu and Debian.

pypdf installs with pip install pypdf and adds one optional dependency set: pip install pypdf[crypto], required for AES encryption and decryption. There is no toolchain, no wheel matrix and no system package. The deployment difference is the one that decides more choices than the API difference does. PyMuPDF puts a binary in your environment; pypdf puts source files there, and every environment that runs Python runs pypdf.

Extraction, tables and the formats you can get out

The output list is where the gap is widest. PyMuPDF's README documents PDF output with full fidelity conversion from Office formats, SVG output as vector page rendering, image output by rasterising at any DPI, structure-aware Markdown described as LLM-ready, JSON containing bounding boxes, layout data and per-element detail, and plain text for fast, lightweight extraction. Tables come back as objects with to_markdown and to_pandas. The README also carries an OCR example against a scanned document, which is the case where a text layer does not exist and something has to be recognised first.

pypdf retrieves text and metadata, and its README describes splitting, merging, reading and creating annotations, and encrypting and decrypting as the rest of the surface. Its analysis is blunt about the boundary: do not expect text extraction to reconstruct complex layouts, and do not adopt it as an OCR engine. A document with two columns, a sidebar and a figure caption will come back as text in an order the layout decided, and the reading order is then your problem.

So the choice at extraction time is about the failure mode you can live with. If the output feeds a retrieval pipeline, a table model or anything where column order and bounding boxes matter, that is PyMuPDF's job and pypdf will not do it. If the output is a page range, a merged output file, a set of passwords or a cleaned metadata record, pypdf does it in a handful of lines, and PyMuPDF can do it too, with a rendering engine carrying a weight you did not need.

Operations, throughput and the shape of a batch job

Rendering is where memory and speed stop being abstract. A pixmap at high DPI on a large page is a large allocation, and a loop that rasterises every page of a long document holds a lot of image data over its lifetime. That is the situation a C engine is built for, and it is also the situation where a default DPI in a loop becomes an incident. Any output that stops at text and index ranges never allocates anything of the sort.

The pypdf batch job is an ordinary Python process: open, operate on pages, write. Its cost is interpreter time on large documents, and its advantage is that scaling it means more workers behind the queue you already run, with no native build and no per-image memory ceiling to reason about. For a service that merges or splits on demand, that is a simpler operational story than shipping a binary into every replica image.

Neither project is a maintenance risk on the evidence available. PyMuPDF's last recorded push is 2026-09-29 and pypdf's is 2026-09-26, and both release lists are recent: PyMuPDF shipped 1.28.2 on 2026-08-06 after 1.28.0 on 2026-06-29, while pypdf shipped 6.19.0 on 2026-09-16 after 6.18.0 on 2026-09-07. The two cadences differ in one visible way. PyMuPDF's numbering is on 1.x with a patch component on some releases, and pypdf is on 6.x with patch releases a few days apart, which is the pattern of a library that takes small changes often. pypdf also ships a pytest suite in the repository, and its README asks contributors for smaller changes and for tests alongside them.

Where PyMuPDF falls short

The licence is the first limit and it is not a small one. PyMuPDF is AGPL-3.0, and our analysis is direct: do not adopt it if you ship closed-source software and cannot comply with those terms. For a service, a library inside a product distributed to customers, or anything networked, that is a decision made with a legal team rather than with a preference, and our analysis also says to read the COPYING file and the licence section of the documentation before committing.

Second, page-level control is work. Every rendering call asks you for a DPI, and every extraction path offers you a choice between flat text, structured text and JSON. The library will not decide, so your code has to, and the tests you write have to cover the decisions. That is a fair trade for precision and a poor trade for a one-off merge.

Third, the feature list is spread across packages. Core PyMuPDF is one command with no dependencies, and then fonts, Markdown extraction, Office formats and OCR are each their own install, with OCR needing a system-level program as well. A product that needs tables and RAG output is running three Python packages and possibly a system binary.

Fourth, our analysis says the engine is the wrong size for simple assembly work. If all you do is split and merge, a permissively licensed pure-Python library is lighter, and the MuPDF engine is weight carried for features you never call.

Where pypdf falls short

There is no rendering. No pixmap, no page image, no DPI, no SVG, no bounding-box JSON, no table detection. A request that arrives as a visual question about a page cannot be answered by this library, and if the answer has to be an image, it has to come from somewhere else.

Text extraction is the second limit. Our analysis tells you not to expect complex layouts to be reconstructed, and the reason is structural: a pure-Python reader working on the content stream has no layout model to consult, so multi-column reading order, headers and figure captions arrive in whatever sequence the file describes. There is also no OCR path, by the same analysis, so a scan yields nothing.

Third, the licence needs reading rather than recognising. The repository is listed under a custom licence that GitHub cannot classify, with the LICENSE file named as the place where the terms are, so a badge will not tell you whether the obligations suit your distribution model. The project's own description calls it free and open source, and that is a claim about intent rather than a list of conditions.

Fourth, upgrade cost. pypdf is the maintained successor to PyPDF2, so older examples in the wild describe a different API, and the README states that 3.1.0 and above include significant improvements compared to previous versions and points at a migration guide. Code and advice written against PyPDF2 is worth checking before it is copied. The pure-Python path is also slower than a C engine for text extraction over large documents, which matters when extraction is the whole job rather than a side effect.

Licence, maintenance and the choice for concrete situations

Put the two licences side by side. PyMuPDF is AGPL-3.0, a licence with a network clause that our analysis treats as a genuine obstacle for closed-source distribution. pypdf is a custom licence whose text lives in the LICENSE file. Neither can be adopted on the strength of a badge, and the practical difference is that the first has widely known terms you can reason about, while the second requires you to read it. If your organisation already has a policy on copyleft with network reach, the first one fails quickly, and that is a feature of the policy rather than a defect of the library.

The situations below are clear enough to decide on.

Invoices and financial tables going into a model. PyMuPDF, because find_tables plus to_pandas is the shortest path from a scanned-looking page to structured rows.

Redacting a document for disclosure. PyMuPDF, because redaction is a page-geometry operation and the other library has no geometry.

A retrieval pipeline over a document archive. PyMuPDF, through the Markdown and JSON output aimed at that use, and OCR for the pages with no text layer.

Splitting or merging on request in a small function, on a platform where shipping a binary is awkward. pypdf, and pip install pypdf[crypto] when the output needs a password.

A closed-source product with any PDF page-surgery requirement. pypdf, and the licence question stops being urgent.

Both in one system is a normal arrangement rather than a conflict. Our analysis describes pypdf as the choice when you need scriptable page-level surgery and cannot ship a native binary, and PyMuPDF as the choice when you need page-level geometry, rendering, redaction or table detection. Nothing prevents a service that extracts tables and renders previews with PyMuPDF from delegating a pure-Python merge step elsewhere, since the two share no internal state.

Before either one goes into a codebase, do what our analysis says for each. For PyMuPDF, install it on your target Python version, run the two documented snippets against one of your own documents, and read COPYING and the licence section of the documentation. For pypdf, run it against your own worst-case file, the awkward one with the unusual producer, and print pypdf.__version__ so any bug report carries the version you actually tested.

Bottom line

PyMuPDF is the choice when the page has to be seen, because rendering, redaction, table detection and bounding-box output are built on a C engine that gives you coordinates to work with, and pypdf is the choice when the page has to be rearranged, because it does splitting, merging, cropping, encryption and metadata in pure Python with nothing compiled to deploy. Both are receiving regular pushes and recent releases, so maintenance is not the deciding factor; the licence is. Verify first that AGPL-3.0 fits your distribution model if you are considering PyMuPDF, that a wheel exists for your Python version and platform or that a toolchain is available, that your hardest document extracts in the reading order you need, and that pypdf's LICENSE file says what you need it to say. The judgement to take away is that this is not a quality comparison, since pypdf is not trying to render anything and PyMuPDF is heavier than a merge requires, so choose by what the page has to become in your pipeline.

Sources

  1. pymupdf/PyMuPDF repository
  2. pymupdf/PyMuPDF README
  3. py-pdf/pypdf repository
  4. py-pdf/pypdf README

Was this useful?