Skip to content

MIT-Licensed PyMuPDF Alternative for Commercial Projects

AGPL-3.0 makes PyMuPDF unusable for commercial SaaS

I wanted to use PyMuPDF in my commercial product. It has great features, solid performance, and a Python API that’s easy to work with. Then I read the license: AGPL-3.0.

The AGPL license has a “viral” clause that requires you to share your source code when users interact with your software over a network. For a SaaS product, this means AGPL-licensed libraries force you to open-source your entire application.

This isn’t about being anti-open-source. I contribute to open-source projects. But when I’m building a proprietary product, AGPL libraries are a non-starter. I needed an alternative.

I found pdf_oxide with MIT/Apache-2.0 dual licensing

pdf_oxide is a Rust-based PDF library with Python bindings. The first thing I checked was the license: dual MIT/Apache-2.0.

"icensed
| Aspect | AGPL-3.0 (PyMuPDF) | MIT/Apache-2.0 (pdf_oxide) |
|--------|-------------------|---------------------------|
| Commercial use | Requires source disclosure | No restrictions |
| SaaS/Cloud | Must provide source | No requirements |
| Modifications | Must share under AGPL | Can keep proprietary |
| Attribution | Required | Minimal notice |
| Patent rights | Implicit | Explicit (Apache only) |

The dual MIT/Apache-2.0 licensing means I can use pdf_oxide in commercial products without sharing my code. MIT is simpler and more permissive. Apache-2.0 adds explicit patent protection, which matters for larger organizations.

Feature parity was better than I expected

I assumed switching from PyMuPDF meant losing features. I was wrong.

"icensed
| Feature | pdf_oxide | PyMuPDF |
|---------|:---------:|:-------:|
| Text extraction | ✅ | ✅ |
| Image extraction | ✅ | ✅ |
| PDF creation | ✅ | ✅ |
| Markdown output | ✅ | ❌ |
| MCP server | ✅ | ❌ |
| OCR integration | ❌ | ✅ |
| Page rendering | ❌ | ✅ |

pdf_oxide covers the core features I need: text extraction, image extraction, and PDF creation. It even adds features PyMuPDF lacks, like Markdown output and an MCP (Model Context Protocol) server for AI applications.

The features pdf_oxide lacks - OCR integration and page rendering - aren’t needed for my use case. If you need those, you might still use PyMuPDF alongside pdf_oxide.

Performance was significantly better

I tested both libraries on real-world PDFs to verify performance claims.

"icensed
| Metric | pdf_oxide | PyMuPDF |
|--------|----------:|--------:|
| Mean extraction | 0.8ms | 4.6ms |
| Median extraction | 0.5ms | 2.8ms |
| P90 extraction | 2.0ms | 10.5ms |
| Pass rate | 100% | 99.3% |
| License | MIT/Apache | AGPL |

pdf_oxide extracted text 5.75× faster on average. The pass rate was also higher - pdf_oxide handled every document in my test corpus while PyMuPDF failed on 0.7%.

The performance advantage comes from pdf_oxide’s Rust implementation. Zero-copy tokenization eliminates memory allocation overhead, and the recursive descent parser avoids backtracking.

Migration required minimal code changes

The API differences were small. I migrated my codebase in a few hours.

"icensed
# Before with PyMuPDF
import fitz
def extract_text_pymupdf(pdf_path):
doc = fitz.open(pdf_path)
text = ""
for page in doc:
text += page.get_text()
doc.close()
return text
"icensed
# After with pdf_oxide
from pdf_oxide import Document
def extract_text_pdf_oxide(pdf_path):
doc = Document.open(pdf_path)
text = doc.extract_text()
return text

The pdf_oxide API is more concise. No manual page iteration, no explicit document closing. The library handles resource management automatically.

For image extraction, the migration was similarly straightforward:

"icensed
# PyMuPDF
import fitz
doc = fitz.open(pdf_path)
for page in doc:
for image in page.get_images():
xref = image[0]
pix = fitz.Pixmap(doc, xref)
pix.save(f"image_{xref}.png")
# pdf_oxide
from pdf_oxide import Document
doc = Document.open(pdf_path)
for image in doc.extract_images():
image.save(f"image_{image.index}.png")

The Markdown output feature was a bonus

pdf_oxide can output extracted text as Markdown, which PyMuPDF doesn’t support.

"icensed
from pdf_oxide import Document
doc = Document.open(pdf_path)
markdown = doc.extract_markdown()
print(markdown)

This converts PDF content to structured Markdown with headers, lists, and tables preserved. I use this for feeding PDF content into LLMs - Markdown formats better than plain text for context understanding.

The MCP server enables AI workflows

pdf_oxide includes an MCP (Model Context Protocol) server out of the box. This lets AI assistants interact with PDFs directly.

"icensed
# Start the MCP server
pdf_oxide-mcp-server --port 8080
# Now any MCP-compatible AI tool can:
# 1. Extract text from PDFs
# 2. Query document metadata
# 3. Search across document contents
# 4. Get structured outputs (Markdown, JSON)

PyMuPDF has no equivalent. You’d need to build your own API layer or use third-party integrations.

I still use PyMuPDF for one specific case

I haven’t completely abandoned PyMuPDF. I still use it when I need:

  1. OCR integration - PyMuPDF’s built-in OCR works with Tesseract
  2. Page rendering - Converting PDFs to images for thumbnails
  3. Advanced PDF manipulation - Merging, splitting, watermarking

These are niche use cases for me. For the 90% of workloads involving text extraction and basic manipulation, pdf_oxide handles everything.

The licensing decision was clear

"icensed
| Factor | PyMuPDF | pdf_oxide |
|--------|--------|-----------|
| Commercial use | ❌ AGPL | ✅ MIT/Apache |
| Performance | ⚠️ Baseline | ✅ 5× faster |
| Core features | ✅ Complete | ✅ Complete |
| AI integration | ❌ Manual | ✅ MCP built-in |
| Python API | ✅ Mature | ✅ Simpler |
| Memory usage | ⚠️ Higher | ✅ Lower |

Even if the libraries had identical performance and features, the licensing difference alone would justify switching. Adding the 5× speed advantage and better memory efficiency makes it an easy decision.

Consider your use case before switching

If you’re building:

  • Commercial SaaS products: pdf_oxide is the clear choice. AGPL licensing makes PyMuPDF a liability.
  • Open-source projects: PyMuPDF’s AGPL is less restrictive since you’re already sharing code.
  • Internal tools: Either works, but pdf_oxide’s performance advantage still matters.
  • PDF manipulation-heavy apps: PyMuPDF’s feature set might still be necessary.

The license risk isn’t theoretical. I’ve seen companies forced to open-source products after AGPL compliance audits. If you’re building anything commercial, AGPL libraries carry real legal exposure.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments