How to Migrate from ZetPDF to IronPDF in C#
ZetPDF is a commercially licensed PDF library for C# applications built on the foundation of the widely-used open-source PDFSharp library. While ZetPDF provides commercial support and basic PDF manipulation capabilities, it inherits significant limitations from its PDFSharp foundation. Most notably, the library relies on coordinate-based graphics programming and offers limited HTML-to-PDF conversion capabilities compared to modern alternatives.
This guide provides a complete migration path from ZetPDF to IronPDF, with step-by-step instructions, code comparisons, and practical examples for professional .NET developers evaluating this transition.
Why Migrate from ZetPDF
ZetPDF, as a fork of PDFSharp, inherits the same architectural constraints that limit its effectiveness for modern document generation workflows. Key reasons development teams consider migration include:
Coordinate-Based API: ZetPDF forces developers to position every element with exact coordinates. Complex manual positioning of every element creates maintenance challenges as requirements change.
Limited CSS Support: No styling system means manual font and color management for every element.
No JavaScript Rendering: Cannot render dynamic web content or execute JavaScript during PDF generation.
Limited Unique Offerings: Compared to using PDFSharp directly for no cost, ZetPDF offers few compelling reasons that necessitate its commercial licensing.
Manual Page Breaks: Must calculate and manage page overflow manually rather than relying on automatic pagination.
Text Measurement Required: Manual calculation for text wrapping creates additional development overhead.
The Fundamental Problem
ZetPDF and PDFSharp force you to position every element with exact coordinates:
// ZetPDF: Manual positioning nightmare
graphics.DrawString("Name:", font, brush, new XPoint(50, 100));
graphics.DrawString("John Doe", font, brush, new XPoint(100, 100));
graphics.DrawString("Address:", font, brush, new XPoint(50, 120));
graphics.DrawString("123 Main St", font, brush, new XPoint(100, 120));
// ... hundreds of lines for a simple form// ZetPDF: Manual positioning nightmare
graphics.DrawString("Name:", font, brush, new XPoint(50, 100));
graphics.DrawString("John Doe", font, brush, new XPoint(100, 100));
graphics.DrawString("Address:", font, brush, new XPoint(50, 120));
graphics.DrawString("123 Main St", font, brush, new XPoint(100, 120));
// ... hundreds of lines for a simple form' ZetPDF: Manual positioning nightmare
graphics.DrawString("Name:", font, brush, New XPoint(50, 100))
graphics.DrawString("John Doe", font, brush, New XPoint(100, 100))
graphics.DrawString("Address:", font, brush, New XPoint(50, 120))
graphics.DrawString("123 Main St", font, brush, New XPoint(100, 120))
' ... hundreds of lines for a simple formIronPDF uses HTML/CSS—the layout engine handles everything:
// IronPDF: Simple HTML
var html = @"
<p><strong>Name:</strong> John Doe</p>
<p><strong>Address:</strong> 123 Main St</p>";
var pdf = renderer.RenderHtmlAsPdf(html);// IronPDF: Simple HTML
var html = @"
<p><strong>Name:</strong> John Doe</p>
<p><strong>Address:</strong> 123 Main St</p>";
var pdf = renderer.RenderHtmlAsPdf(html);IRON VB CONVERTER ERROR developers@ironsoftware.comIronPDF vs ZetPDF: Feature Comparison
Understanding the architectural differences helps technical decision-makers evaluate the migration investment:
| Feature | ZetPDF | IronPDF |
|---|---|---|
| Based on PDFSharp | Yes | No |
| HTML-to-PDF Conversion | Limited | Yes (Full Chromium) |
| Commercial License | Yes, Perpetual | Yes |
| Open Source Foundation | PDFSharp (MIT License) | Chromium-based |
| CSS Support | No | Full CSS3 |
| JavaScript | No | Full ES2024 |
| Automatic Layout | No | Yes |
| Auto Page Breaks | No | Yes |
| Tables | Manual drawing | HTML <table> |
| Headers/Footers | Manual | HTML/CSS |
| Watermarks | Manual code | Built-in |
| Merge PDFs | Limited | Yes |
| Split PDFs | Limited | Yes |
| Digital Signatures | No | Yes |
| PDF/A | No | Yes |
| Simplicity and Ease of Use | Moderate | High |
Quick Start: ZetPDF to IronPDF Migration
The migration can begin immediately with these foundational steps.
Step 1: Replace NuGet Package
Remove ZetPDF:
# Remove ZetPDF
dotnet remove package ZetPDF# Remove ZetPDF
dotnet remove package ZetPDFInstall IronPDF:
# Install IronPDF
dotnet add package IronPdf# Install IronPDF
dotnet add package IronPdfStep 2: Update Namespaces
Replace ZetPDF namespaces with the IronPdf namespace:
// Before (ZetPDF)
using ZetPdf;
using ZetPdf.Drawing;
using ZetPdf.Fonts;
// After (IronPDF)
using IronPdf;// Before (ZetPDF)
using ZetPdf;
using ZetPdf.Drawing;
using ZetPdf.Fonts;
// After (IronPDF)
using IronPdf;IRON VB CONVERTER ERROR developers@ironsoftware.comStep 3: Initialize License
Add license initialization at application startup:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"Code Migration Examples
Converting HTML to PDF
The HTML-to-PDF operation demonstrates the API differences between these .NET PDF libraries.
ZetPDF Approach:
// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
class Program
{
static void Main()
{
var converter = new HtmlToPdfConverter();
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
converter.ConvertHtmlToPdf(htmlContent, "output.pdf");
Console.WriteLine("PDF created successfully");
}
}// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
class Program
{
static void Main()
{
var converter = new HtmlToPdfConverter();
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
converter.ConvertHtmlToPdf(htmlContent, "output.pdf");
Console.WriteLine("PDF created successfully");
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comIronPDF Approach:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comZetPDF uses HtmlToPdfConverter with ConvertHtmlToPdf() that writes directly to a file path. IronPDF provides ChromePdfRenderer with RenderHtmlAsPdf() that returns a PdfDocument object, giving you more flexibility with the output—you can save to file, get binary data, or perform additional operations before saving.
For advanced HTML-to-PDF scenarios, see the HTML to PDF conversion guide.
Converting URLs to PDF
URL-to-PDF conversion shows the pattern differences clearly.
ZetPDF Approach:
// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
class Program
{
static void Main()
{
var converter = new HtmlToPdfConverter();
var url = "https://www.example.com";
converter.ConvertUrlToPdf(url, "webpage.pdf");
Console.WriteLine("PDF from URL created successfully");
}
}// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
class Program
{
static void Main()
{
var converter = new HtmlToPdfConverter();
var url = "https://www.example.com";
converter.ConvertUrlToPdf(url, "webpage.pdf");
Console.WriteLine("PDF from URL created successfully");
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comIronPDF Approach:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var url = "https://www.example.com";
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL created successfully");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var url = "https://www.example.com";
var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL created successfully");
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comZetPDF uses the same HtmlToPdfConverter class with ConvertUrlToPdf(). IronPDF provides RenderUrlAsPdf() on ChromePdfRenderer, which leverages a full Chromium rendering engine for accurate web page capture including JavaScript execution and modern CSS.
Explore the URL to PDF documentation for authentication and custom header options.
Merging Multiple PDFs
PDF merging reveals significant API differences in how documents are handled.
ZetPDF Approach:
// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var merger = new PdfMerger();
var files = new List<string> { "document1.pdf", "document2.pdf" };
merger.MergeFiles(files, "merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var merger = new PdfMerger();
var files = new List<string> { "document1.pdf", "document2.pdf" };
merger.MergeFiles(files, "merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comIronPDF Approach:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdfs = new List<PdfDocument>
{
PdfDocument.FromFile("document1.pdf"),
PdfDocument.FromFile("document2.pdf")
};
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var pdfs = new List<PdfDocument>
{
PdfDocument.FromFile("document1.pdf"),
PdfDocument.FromFile("document2.pdf")
};
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs("merged.pdf");
Console.WriteLine("PDFs merged successfully");
}
}IRON VB CONVERTER ERROR developers@ironsoftware.comZetPDF uses a dedicated PdfMerger class that operates on file paths with MergeFiles(). IronPDF loads documents as PdfDocument objects using PdfDocument.FromFile(), then merges them with the static PdfDocument.Merge() method. This object-oriented approach enables additional operations on the merged document before saving.
Explore the PDF merging documentation for additional merge options.
Coordinate-Based Drawing vs HTML
For developers with existing ZetPDF code using coordinate-based graphics, the migration path involves converting drawing commands to HTML/CSS.
ZetPDF Coordinate-Based Approach:
using ZetPdf;
using ZetPdf.Drawing;
var document = new PdfDocument();
var page = document.AddPage();
page.Width = XUnit.FromMillimeter(210);
page.Height = XUnit.FromMillimeter(297);
var graphics = XGraphics.FromPdfPage(page);
var titleFont = new XFont("Arial", 24, XFontStyle.Bold);
var bodyFont = new XFont("Arial", 12);
graphics.DrawString("Company Report", titleFont, XBrushes.Navy,
new XPoint(50, 50));
graphics.DrawString("This is the introduction paragraph.", bodyFont, XBrushes.Black,
new XPoint(50, 80));
graphics.DrawString("Generated: " + DateTime.Now.ToString(), bodyFont, XBrushes.Gray,
new XPoint(50, 100));
document.Save("report.pdf");using ZetPdf;
using ZetPdf.Drawing;
var document = new PdfDocument();
var page = document.AddPage();
page.Width = XUnit.FromMillimeter(210);
page.Height = XUnit.FromMillimeter(297);
var graphics = XGraphics.FromPdfPage(page);
var titleFont = new XFont("Arial", 24, XFontStyle.Bold);
var bodyFont = new XFont("Arial", 12);
graphics.DrawString("Company Report", titleFont, XBrushes.Navy,
new XPoint(50, 50));
graphics.DrawString("This is the introduction paragraph.", bodyFont, XBrushes.Black,
new XPoint(50, 80));
graphics.DrawString("Generated: " + DateTime.Now.ToString(), bodyFont, XBrushes.Gray,
new XPoint(50, 100));
document.Save("report.pdf");IRON VB CONVERTER ERROR developers@ironsoftware.comIronPDF HTML Approach:
using IronPdf;
var html = $@"
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; padding: 50px; }}
h1 {{ color: navy; }}
.date {{ color: gray; }}
</style>
</head>
<body>
<h1>Company Report</h1>
<p>This is the introduction paragraph.</p>
<p class='date'>Generated: {DateTime.Now}</p>
</body>
</html>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("report.pdf");using IronPdf;
var html = $@"
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; padding: 50px; }}
h1 {{ color: navy; }}
.date {{ color: gray; }}
</style>
</head>
<body>
<h1>Company Report</h1>
<p>This is the introduction paragraph.</p>
<p class='date'>Generated: {DateTime.Now}</p>
</body>
</html>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("report.pdf");IRON VB CONVERTER ERROR developers@ironsoftware.comThe ZetPDF approach requires creating font objects, calculating exact pixel positions, and manually managing the graphics context. The IronPDF approach uses standard HTML and CSS that web developers already know—fonts, colors, and layout are handled through familiar CSS properties.
ZetPDF API to IronPDF Mapping Reference
This mapping accelerates migration by showing direct API equivalents:
| ZetPDF | IronPDF |
|---|---|
new PdfDocument() | new ChromePdfRenderer() |
document.AddPage() | Automatic |
XGraphics.FromPdfPage(page) | N/A |
graphics.DrawString() | HTML text elements |
graphics.DrawImage() | <img> tag |
graphics.DrawLine() | CSS borders |
graphics.DrawRectangle() | CSS border + div |
new XFont() | CSS font-family |
XBrushes.Black | CSS color |
document.Save() | pdf.SaveAs() |
PdfReader.Open() | PdfDocument.FromFile() |
HtmlToPdfConverter | ChromePdfRenderer |
ConvertHtmlToPdf() | RenderHtmlAsPdf() |
ConvertUrlToPdf() | RenderUrlAsPdf() |
PdfMerger | PdfDocument.Merge() |
Common Migration Issues and Solutions
Issue 1: Coordinate-Based Layout
ZetPDF: Everything requires exact X,Y coordinates with manual positioning.
Solution: Use HTML/CSS flow layout. For absolute positioning when needed, use CSS:
.positioned-element {
position: absolute;
top: 100px;
left: 50px;
}Issue 2: Font Object Management
ZetPDF: Create XFont objects for each font variation.
Solution: Use CSS font-family—fonts are handled automatically:
<style>
body { font-family: Arial, sans-serif; }
h1 { font-family: 'Times New Roman', serif; font-size: 24px; font-weight: bold; }
</style><style>
body { font-family: Arial, sans-serif; }
h1 { font-family: 'Times New Roman', serif; font-size: 24px; font-weight: bold; }
</style>Issue 3: Color Handling
ZetPDF: Use XBrushes and color objects.
Solution: Use standard CSS colors:
.header { color: navy; background-color: #f5f5f5; }
.warning { color: rgb(255, 0, 0); }Issue 4: Manual Page Breaks
ZetPDF: Track Y position and create new pages manually when content overflows.
Solution: IronPDF handles automatic page breaks. For explicit control, use CSS:
.section { page-break-after: always; }
.keep-together { page-break-inside: avoid; }Issue 5: Table Creation
ZetPDF: Requires manual drawing of rectangles, lines, and text positioning.
Solution: Use standard HTML tables with CSS styling:
<table style="border-collapse: collapse; width: 100%;">
<tr>
<th style="border: 1px solid black; padding: 8px;">Header</th>
</tr>
<tr>
<td style="border: 1px solid black; padding: 8px;">Data</td>
</tr>
</table><table style="border-collapse: collapse; width: 100%;">
<tr>
<th style="border: 1px solid black; padding: 8px;">Header</th>
</tr>
<tr>
<td style="border: 1px solid black; padding: 8px;">Data</td>
</tr>
</table>ZetPDF Migration Checklist
Pre-Migration Tasks
Audit your codebase to identify all ZetPDF usage:
grep -r "using ZetPDF" --include="*.cs" .
grep -r "HtmlToPdfConverter\|PdfMerger\|XGraphics" --include="*.cs" .grep -r "using ZetPDF" --include="*.cs" .
grep -r "HtmlToPdfConverter\|PdfMerger\|XGraphics" --include="*.cs" .Document coordinate-based drawing code that needs conversion to HTML. Note font and color usage patterns. Map layout structures to HTML equivalents.
Code Update Tasks
- Remove ZetPDF NuGet package
- Install IronPdf NuGet package
- Update namespace imports from
ZetPDFtoIronPdf - Replace
HtmlToPdfConverterwithChromePdfRenderer - Convert
ConvertHtmlToPdf()calls toRenderHtmlAsPdf()+SaveAs() - Convert
ConvertUrlToPdf()calls toRenderUrlAsPdf()+SaveAs() - Replace
PdfMerger.MergeFiles()withPdfDocument.Merge() - Convert
DrawString()calls to HTML text elements - Convert
XFontto CSSfont-family - Replace
XBrusheswith CSS colors - Add IronPDF license initialization at startup
Post-Migration Testing
After migration, verify these aspects:
- Compare visual output to ensure appearance matches or improves
- Verify fonts render as expected with CSS styling
- Test page breaks occur correctly with automatic pagination
- Verify images are positioned and displayed correctly
- Test PDF merging operations produce correct output
- Confirm all existing functionality works with the new implementation
Key Benefits of Migrating to IronPDF
Moving from ZetPDF to IronPDF provides several critical advantages:
Modern Chromium Rendering Engine: IronPDF uses Chromium for HTML-to-PDF conversion, ensuring full CSS3 and ES2024 JavaScript support. Modern frameworks and responsive designs render correctly.
HTML-Based Content Creation: Web developers can leverage existing HTML and CSS skills. No need to learn coordinate-based drawing APIs or manage font objects.
Automatic Layout and Pagination: Text wrapping, page breaks, and flow layout happen automatically. No manual calculation of element positions.
Simplified API: Single-method calls for common operations. PdfDocument.Merge() replaces complex file path handling patterns.
Active Development: As .NET 10 and C# 14 adoption increases through 2026, IronPDF's regular updates ensure compatibility with current and future .NET versions.
Comprehensive Feature Set: Built-in watermarking, digital signatures, PDF/A compliance, and advanced PDF manipulation features that ZetPDF lacks.






