Skip to footer content
MIGRATION GUIDES

How to Migrate from MuPDF to IronPDF in C#

Why Migrate from MuPDF to IronPDF

The MuPDF Challenges

MuPDF is an excellent PDF renderer, but its AGPL license and rendering-only focus create significant limitations for .NET developers building commercial applications:

  1. AGPL License Trap: MuPDF's viral licensing requires either open-sourcing your entire application under AGPL or purchasing expensive commercial licenses with opaque, contact-sales pricing.

  2. Rendering-Only Focus: MuPDF is a viewer/renderer—it's not designed for PDF creation from HTML, document generation workflows, form filling, or adding watermarks and headers/footers.

  3. No HTML Support: MuPDF does not support direct HTML to PDF conversion. You would need to use another library to convert HTML to a supported format first. This is a fundamental limitation—MuPDF is primarily a PDF renderer/viewer.

  4. Native Dependencies: Platform-specific binaries require manual management for Windows, Linux, and macOS. Docker deployments become complex with native library requirements, and deployment packaging introduces challenges.

  5. Limited Manipulation: No built-in support for merging/splitting PDFs, page rotation or reordering, watermarks or annotations, or digital signatures.

  6. C Interop Complexity: Native bindings introduce memory management concerns, platform-specific bugs, and marshalling overhead.

MuPDF vs IronPDF Comparison

FeatureMuPDFIronPDF
LicenseAGPL (viral) or expensive commercialCommercial with transparent pricing
Primary FocusRendering/viewingComplete PDF solution
HTML to PDFNot supportedFull Chromium engine
PDF CreationNot supportedHTML, URL, images
PDF ManipulationLimitedComplete (merge, split, edit)
DependenciesNative binariesFully managed
Platform SupportManual per-platformAutomatic
Async SupportLimitedFull async/await
.NET IntegrationC interopNative .NET

For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a future-proof foundation as a fully managed .NET library without native interop complexity.


Migration Complexity Assessment

Estimated Effort by Feature

FeatureMigration ComplexityNotes
Document LoadingVery LowDirect method replacement
Text ExtractionVery LowSimpler API
PDF MergingLowStatic method vs manual loops
Image RenderingLowRasterizeToImageFiles vs pixmaps
HTML to PDFN/A (New Capability)Not possible in MuPDF
Security/WatermarksN/A (New Capability)Not possible in MuPDF

Paradigm Shift

The fundamental shift in this MuPDF migration is from rendering-only viewer to complete PDF solution:

MuPDF:   MuPDFContext → MuPDFDocument → Page iteration → Render/Extract only
IronPDF: PdfDocument.FromFile() → Full manipulation → Create/Edit/Merge/Secure

Before You Start

Prerequisites

  1. .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet Access: Ability to install NuGet packages
  3. IronPDF License: Obtain your license key from ironpdf.com

NuGet Package Changes

# Remove MuPDF packages
dotnet remove package MuPDF.NET
dotnet remove package MuPDFCore
dotnet remove package MuPDFCore.MuPDFWrapper

# Install IronPDF
dotnet add package IronPdf
# Remove MuPDF packages
dotnet remove package MuPDF.NET
dotnet remove package MuPDFCore
dotnet remove package MuPDFCore.MuPDFWrapper

# Install IronPDF
dotnet add package IronPdf
SHELL

Also remove native MuPDF binaries from your deployment:

  • Delete mupdf.dll, libmupdf.so, libmupdf.dylib
  • Remove platform-specific folders (runtimes/*/native/)
  • Update Docker files to remove MuPDF installation

License Configuration

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Identify MuPDF Usage

# Find all MuPDF references
grep -r "MuPDF\|MuPDFCore\|MuPDFDocument" --include="*.cs" .
# Find all MuPDF references
grep -r "MuPDF\|MuPDFCore\|MuPDFDocument" --include="*.cs" .
SHELL

Complete API Reference

Document Loading

MuPDFIronPDFNotes
new MuPDFDocument(path)PdfDocument.FromFile(path)Load from file
new MuPDFDocument(stream)PdfDocument.FromStream(stream)Load from stream
document.Dispose()pdf.Dispose()Cleanup

Page Access

MuPDFIronPDFNotes
document.Pages.Countpdf.PageCountPage count
document.Pages[index]pdf.Pages[index]Access page
page.GetText()page.TextPage text

Text Extraction

MuPDFIronPDFNotes
Loop through document.Pages[i].GetText()pdf.ExtractAllText()All text at once

PDF Creation (Not Available in MuPDF)

MuPDFIronPDFNotes
(not supported)ChromePdfRenderer.RenderHtmlAsPdf(html)HTML to PDF
(not supported)ChromePdfRenderer.RenderUrlAsPdf(url)URL to PDF

PDF Manipulation (Limited in MuPDF)

MuPDFIronPDFNotes
Manual page copy loopsPdfDocument.Merge(pdf1, pdf2)Merge PDFs
(not supported)pdf.ApplyWatermark(html)Add watermark
(not supported)pdf.SecuritySettingsPassword protection

Code Migration Examples

Example 1: HTML to PDF Conversion (MuPDF Cannot Do This)

Before (MuPDF):

// NuGet: Install-Package MuPDF.NET
using MuPDFCore;
using System.IO;

class Program
{
    static void Main()
    {
        // MuPDF doesn't support HTML to PDF conversion directly
        // You would need to use another library to convert HTML to a supported format first
        // This is a limitation - MuPDF is primarily a PDF renderer/viewer

        // Alternative: Use a browser engine or intermediate conversion
        string html = "<html><body><h1>Hello World</h1></body></html>";

        // Not natively supported in MuPDF
        throw new NotSupportedException("MuPDF does not support direct HTML to PDF conversion");
    }
}
// NuGet: Install-Package MuPDF.NET
using MuPDFCore;
using System.IO;

class Program
{
    static void Main()
    {
        // MuPDF doesn't support HTML to PDF conversion directly
        // You would need to use another library to convert HTML to a supported format first
        // This is a limitation - MuPDF is primarily a PDF renderer/viewer

        // Alternative: Use a browser engine or intermediate conversion
        string html = "<html><body><h1>Hello World</h1></body></html>";

        // Not natively supported in MuPDF
        throw new NotSupportedException("MuPDF does not support direct HTML to PDF conversion");
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<html><body><h1>Hello World</h1></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<html><body><h1>Hello World</h1></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

This example highlights MuPDF's most significant limitation: it cannot convert HTML to PDF at all. The MuPDF code explicitly throws NotSupportedException because HTML-to-PDF conversion is simply not a capability MuPDF provides. If you needed this functionality with MuPDF, you had to use a separate library like wkhtmltopdf or a browser engine, then load the resulting PDF with MuPDF for viewing.

IronPDF's ChromePdfRenderer uses a full Chromium engine to render HTML with complete CSS3, JavaScript, and modern web standards support. The RenderHtmlAsPdf() method accepts HTML strings directly. See the HTML to PDF documentation for additional rendering options including URL rendering and HTML file conversion.

Example 2: Text Extraction

Before (MuPDF):

// NuGet: Install-Package MuPDF.NET
using MuPDFCore;
using System;
using System.Text;

class Program
{
    static void Main()
    {
        using (MuPDFDocument document = new MuPDFDocument("input.pdf"))
        {
            StringBuilder allText = new StringBuilder();

            for (int i = 0; i < document.Pages.Count; i++)
            {
                string pageText = document.Pages[i].GetText();
                allText.AppendLine(pageText);
            }

            Console.WriteLine(allText.ToString());
        }
    }
}
// NuGet: Install-Package MuPDF.NET
using MuPDFCore;
using System;
using System.Text;

class Program
{
    static void Main()
    {
        using (MuPDFDocument document = new MuPDFDocument("input.pdf"))
        {
            StringBuilder allText = new StringBuilder();

            for (int i = 0; i < document.Pages.Count; i++)
            {
                string pageText = document.Pages[i].GetText();
                allText.AppendLine(pageText);
            }

            Console.WriteLine(allText.ToString());
        }
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var pdf = PdfDocument.FromFile("input.pdf");
        string text = pdf.ExtractAllText();

        Console.WriteLine(text);
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var pdf = PdfDocument.FromFile("input.pdf");
        string text = pdf.ExtractAllText();

        Console.WriteLine(text);
    }
}
$vbLabelText   $csharpLabel

The MuPDF approach requires creating a using block with a MuPDFDocument, manually iterating through document.Pages.Count with a for loop, calling document.Pages[i].GetText() for each page, and building up the text with a StringBuilder. This is 12 lines of code for a simple text extraction.

IronPDF reduces this to 3 lines: load the document with PdfDocument.FromFile(), call ExtractAllText(), and print the result. No manual iteration, no StringBuilder, no explicit resource management with using blocks for this simple operation. Learn more about text extraction from PDFs.

Example 3: Merging Multiple PDFs

Before (MuPDF):

// NuGet: Install-Package MuPDF.NET
using MuPDFCore;
using System.IO;

class Program
{
    static void Main()
    {
        using (MuPDFDocument doc1 = new MuPDFDocument("file1.pdf"))
        using (MuPDFDocument doc2 = new MuPDFDocument("file2.pdf"))
        {
            // Create a new document
            using (MuPDFDocument mergedDoc = MuPDFDocument.Create())
            {
                // Copy pages from first document
                for (int i = 0; i < doc1.Pages.Count; i++)
                {
                    mergedDoc.CopyPage(doc1, i);
                }

                // Copy pages from second document
                for (int i = 0; i < doc2.Pages.Count; i++)
                {
                    mergedDoc.CopyPage(doc2, i);
                }

                mergedDoc.Save("merged.pdf");
            }
        }
    }
}
// NuGet: Install-Package MuPDF.NET
using MuPDFCore;
using System.IO;

class Program
{
    static void Main()
    {
        using (MuPDFDocument doc1 = new MuPDFDocument("file1.pdf"))
        using (MuPDFDocument doc2 = new MuPDFDocument("file2.pdf"))
        {
            // Create a new document
            using (MuPDFDocument mergedDoc = MuPDFDocument.Create())
            {
                // Copy pages from first document
                for (int i = 0; i < doc1.Pages.Count; i++)
                {
                    mergedDoc.CopyPage(doc1, i);
                }

                // Copy pages from second document
                for (int i = 0; i < doc2.Pages.Count; i++)
                {
                    mergedDoc.CopyPage(doc2, i);
                }

                mergedDoc.Save("merged.pdf");
            }
        }
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var pdf1 = PdfDocument.FromFile("file1.pdf");
        var pdf2 = PdfDocument.FromFile("file2.pdf");

        var merged = PdfDocument.Merge(pdf1, pdf2);
        merged.SaveAs("merged.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var pdf1 = PdfDocument.FromFile("file1.pdf");
        var pdf2 = PdfDocument.FromFile("file2.pdf");

        var merged = PdfDocument.Merge(pdf1, pdf2);
        merged.SaveAs("merged.pdf");
    }
}
$vbLabelText   $csharpLabel

The MuPDF merge operation is particularly verbose. You must open both source documents in nested using blocks, create a new empty document with MuPDFDocument.Create(), iterate through each page of the first document calling CopyPage(), iterate through each page of the second document calling CopyPage(), and finally save. That's 20+ lines of code with complex nesting.

IronPDF's static PdfDocument.Merge() method accepts multiple PDF documents and returns a single merged document. The entire operation is 4 lines of readable code. For merging many documents, you can pass a list: PdfDocument.Merge(pdfList). See the merge and split PDFs documentation for additional options.


Critical Migration Notes

Remove Native Binaries

MuPDF requires platform-specific native libraries. After migrating to IronPDF, remove all MuPDF native binaries:

# Delete native libraries
rm -f mupdf*.dll libmupdf*.so libmupdf*.dylib

# Remove runtime folders
rm -rf runtimes/*/native/

# Update Docker files to remove MuPDF installation
# Delete native libraries
rm -f mupdf*.dll libmupdf*.so libmupdf*.dylib

# Remove runtime folders
rm -rf runtimes/*/native/

# Update Docker files to remove MuPDF installation
SHELL

IronPDF is fully managed .NET code—no native binaries to manage across platforms.

Dispose Pattern Simplified

MuPDF requires explicit context and document management:

// MuPDF: Nested using blocks required
using (MuPDFDocument document = new MuPDFDocument("input.pdf"))
{
    // Work with document
}

// IronPDF: Simpler pattern
var pdf = PdfDocument.FromFile("input.pdf");
// Work with pdf
// MuPDF: Nested using blocks required
using (MuPDFDocument document = new MuPDFDocument("input.pdf"))
{
    // Work with document
}

// IronPDF: Simpler pattern
var pdf = PdfDocument.FromFile("input.pdf");
// Work with pdf
$vbLabelText   $csharpLabel

Page Iteration Pattern Change

MuPDF uses index-based iteration with explicit page count:

// MuPDF
for (int i = 0; i < document.Pages.Count; i++)
{
    var pageText = document.Pages[i].GetText();
}

// IronPDF (foreach supported)
foreach (var page in pdf.Pages)
{
    var pageText = page.Text;
}
// MuPDF
for (int i = 0; i < document.Pages.Count; i++)
{
    var pageText = document.Pages[i].GetText();
}

// IronPDF (foreach supported)
foreach (var page in pdf.Pages)
{
    var pageText = page.Text;
}
$vbLabelText   $csharpLabel

New Capabilities Available

After migrating to IronPDF, you gain capabilities that MuPDF cannot provide:

// PDF Creation from HTML (not possible in MuPDF)
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello</h1>");

// Watermarks (not possible in MuPDF)
pdf.ApplyWatermark("<div style='color:red;opacity:0.3;'>DRAFT</div>");

// Password Protection (not possible in MuPDF)
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "user";

// Headers and Footers (not possible in MuPDF)
pdf.AddTextHeader("Document Title");
pdf.AddTextFooter("Page {page} of {total-pages}");
// PDF Creation from HTML (not possible in MuPDF)
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello</h1>");

// Watermarks (not possible in MuPDF)
pdf.ApplyWatermark("<div style='color:red;opacity:0.3;'>DRAFT</div>");

// Password Protection (not possible in MuPDF)
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "user";

// Headers and Footers (not possible in MuPDF)
pdf.AddTextHeader("Document Title");
pdf.AddTextFooter("Page {page} of {total-pages}");
$vbLabelText   $csharpLabel

Troubleshooting

Issue 1: MuPDFDocument Not Found

Problem: MuPDFDocument class doesn't exist in IronPDF.

Solution: Use PdfDocument.FromFile():

// MuPDF
using (MuPDFDocument document = new MuPDFDocument("input.pdf"))

// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
// MuPDF
using (MuPDFDocument document = new MuPDFDocument("input.pdf"))

// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");
$vbLabelText   $csharpLabel

Issue 2: Pages.Count Not Found

Problem: document.Pages.Count pattern doesn't work.

Solution: Use pdf.PageCount:

// MuPDF
for (int i = 0; i < document.Pages.Count; i++)

// IronPDF
for (int i = 0; i < pdf.PageCount; i++)
// Or use: foreach (var page in pdf.Pages)
// MuPDF
for (int i = 0; i < document.Pages.Count; i++)

// IronPDF
for (int i = 0; i < pdf.PageCount; i++)
// Or use: foreach (var page in pdf.Pages)
$vbLabelText   $csharpLabel

Issue 3: GetText() Not Found

Problem: page.GetText() method doesn't exist.

Solution: Use page.Text property or pdf.ExtractAllText():

// MuPDF
string pageText = document.Pages[i].GetText();

// IronPDF
string pageText = pdf.Pages[i].Text;
// Or for all text:
string allText = pdf.ExtractAllText();
// MuPDF
string pageText = document.Pages[i].GetText();

// IronPDF
string pageText = pdf.Pages[i].Text;
// Or for all text:
string allText = pdf.ExtractAllText();
$vbLabelText   $csharpLabel

Issue 4: CopyPage Not Found

Problem: Manual page copying pattern for merging.

Solution: Use static PdfDocument.Merge():

// MuPDF
mergedDoc.CopyPage(doc1, i);

// IronPDF
var merged = PdfDocument.Merge(pdf1, pdf2);
// MuPDF
mergedDoc.CopyPage(doc1, i);

// IronPDF
var merged = PdfDocument.Merge(pdf1, pdf2);
$vbLabelText   $csharpLabel

Migration Checklist

Pre-Migration

  • Inventory all MuPDF usages in codebase
  • Document all rendering operations (DPI, scale factors)
  • Identify any PDF creation needs (currently using external tools)
  • List text extraction requirements
  • Review deployment scripts for native binary handling
  • Obtain IronPDF license key

Package Changes

  • Remove MuPDF.NET package
  • Remove MuPDFCore package
  • Remove MuPDFCore.MuPDFWrapper package
  • Install IronPdf NuGet package: dotnet add package IronPdf
  • Update namespace imports

Code Changes

  • Add license key configuration at startup
  • Replace MuPDFDocument with PdfDocument.FromFile()
  • Replace document.Pages.Count with pdf.PageCount
  • Replace page.GetText() with page.Text or pdf.ExtractAllText()
  • Replace manual CopyPage loops with PdfDocument.Merge()
  • Remove nested using blocks for context management
  • Add PDF creation code if needed (HTML to PDF)

Post-Migration

  • Remove native MuPDF binaries from project
  • Update Docker files to remove MuPDF installation
  • Remove platform-specific runtime folders
  • Run regression tests comparing rendered output
  • Test on all target platforms (Windows, Linux, macOS)
  • Consider adding new capabilities (watermarks, security, headers/footers)

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More