How to Migrate from Spire.PDF to IronPDF in C#
Migrating from Spire.PDF to IronPDF transforms your PDF generation workflow from a library that renders text as images to one that produces true, selectable, searchable text using a modern Chromium rendering engine. This guide provides a complete, step-by-step migration path that resolves Spire.PDF's critical HTML rendering limitations and font embedding issues.
Why Migrate from Spire.PDF to IronPDF
Understanding Spire.PDF
Spire.PDF is a robust, commercial PDF library designed for .NET developers to handle PDF documents efficiently. Spire.PDF has made its mark in the programming community for its specific capabilities, especially in legacy applications, and its integration capabilities seamlessly align with other components in the E-iceblue set of tools.
However, Spire.PDF has several fundamental problems that affect real-world usage, particularly around HTML-to-PDF conversion and modern web standards support.
Critical Technical Issues
| Issue | Impact | IronPDF Solution |
|---|---|---|
| Text rendered as images | PDFs not searchable, not accessible, can't copy text | Real text rendering |
| Internet Explorer dependency | Outdated rendering, security risks | Modern Chromium engine |
| Font embedding failures | Documents look wrong on other systems | Reliable font handling |
| Large deployment footprint | High memory usage, slow startup | Efficient deployment |
| Limited CSS support | Modern layouts don't render correctly | Full CSS3 support |
The Core Problem: Image-Based PDFs
One significant drawback of Spire.PDF is its inclination to render text within HTML documents as images. This results in PDFs where text is not selectable or searchable, which can be a serious limitation for applications necessitating search functionality or document text interaction.
When you use Spire.PDF's LoadFromHTML() method, it often renders text as bitmap images rather than actual text, creating these problems:
- Text CANNOT be selected
- Text CANNOT be searched
- Text CANNOT be copied
- Screen readers CANNOT read it (accessibility violation)
- File size is MUCH larger
- Zooming causes pixelation
Spire.PDF vs IronPDF Comparison
| Feature | Spire.PDF | IronPDF |
|---|---|---|
| HTML to PDF Rendering | Text rendered as images | True text rendering (selectable and searchable) |
| Rendering Engine | Internet Explorer dependent on some systems | Chromium-based, modern web standards compliant |
| Font Handling | Known issues with font embedding | Reliable and robust font handling |
| CSS3 Support | Limited | Full |
| Flexbox/Grid | Not supported | Full support |
| JavaScript | Limited | Full ES6+ |
| PDF Accessibility | Poor (image-based) | Excellent |
| API Design | Complex | Simple and intuitive |
| Deployment Footprint | Large | Moderate |
| Licensing | Freemium/Commercial | Commercial |
For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF resolves critical issues with Spire.PDF's HTML-to-PDF conversion by rendering text as actual selectable text rather than images, ensuring PDFs are searchable and accessible.
Before You Start
Prerequisites
- .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet Access: Ability to install NuGet packages
- IronPDF License: Obtain your license key from ironpdf.com
NuGet Package Changes
# Remove Spire.PDF
dotnet remove package Spire.PDF
dotnet remove package FreeSpire.PDF # If using free version
# Install IronPDF
dotnet add package IronPdf# Remove Spire.PDF
dotnet remove package Spire.PDF
dotnet remove package FreeSpire.PDF # If using free version
# Install IronPDF
dotnet add package IronPdfLicense Configuration
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";Complete API Reference
Namespace Changes
// Before: Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.HtmlConverter;
// After: IronPDF
using IronPdf;
using IronPdf.Editing;// Before: Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using Spire.Pdf.HtmlConverter;
// After: IronPDF
using IronPdf;
using IronPdf.Editing;Core API Mappings
| Spire.PDF | IronPDF | Notes |
|---|---|---|
new PdfDocument() | new ChromePdfRenderer() | For HTML rendering |
pdf.LoadFromHTML() | renderer.RenderHtmlAsPdf() | HTML conversion |
pdf.LoadFromFile() | PdfDocument.FromFile() | Load existing PDF |
pdf.SaveToFile() | pdf.SaveAs() | Save to file |
pdf.Close() | Not needed | Uses dispose pattern |
pdf.Pages.Add() | renderer.RenderHtmlAsPdf() | Create page from HTML |
pdf.InsertPageRange() | PdfDocument.Merge() | Merge PDFs |
page.Canvas.DrawString() | TextStamper + ApplyStamp() | Add text |
PdfFont | CSS styling in HTML | Font configuration |
PdfBrush | CSS styling in HTML | Color/fill configuration |
Code Migration Examples
Example 1: HTML to PDF Conversion
Before (Spire.PDF):
// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfHtmlLayoutFormat htmlLayoutFormat = new PdfHtmlLayoutFormat();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
pdf.LoadFromHTML(htmlString, false, true, true);
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfHtmlLayoutFormat htmlLayoutFormat = new PdfHtmlLayoutFormat();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
pdf.LoadFromHTML(htmlString, false, true, true);
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlString);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlString = "<html><body><h1>Hello World</h1><p>This is a PDF from HTML.</p></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlString);
pdf.SaveAs("output.pdf");
}
}This example demonstrates the fundamental difference in HTML rendering. Spire.PDF uses LoadFromHTML() with a PdfHtmlLayoutFormat object, which often renders text as bitmap images. The result is PDFs where users cannot select, copy, or search text.
IronPDF uses a ChromePdfRenderer with RenderHtmlAsPdf(), producing true text that is fully selectable, searchable, and accessible. No Close() call is required—IronPDF uses the dispose pattern for automatic cleanup. See the HTML to PDF documentation for comprehensive examples.
Example 2: Merging Multiple PDFs
Before (Spire.PDF):
// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using System;
class Program
{
static void Main()
{
PdfDocument pdf1 = new PdfDocument();
pdf1.LoadFromFile("document1.pdf");
PdfDocument pdf2 = new PdfDocument();
pdf2.LoadFromFile("document2.pdf");
pdf1.InsertPageRange(pdf2, 0, pdf2.Pages.Count - 1);
pdf1.SaveToFile("merged.pdf");
pdf1.Close();
pdf2.Close();
}
}// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using System;
class Program
{
static void Main()
{
PdfDocument pdf1 = new PdfDocument();
pdf1.LoadFromFile("document1.pdf");
PdfDocument pdf2 = new PdfDocument();
pdf2.LoadFromFile("document2.pdf");
pdf1.InsertPageRange(pdf2, 0, pdf2.Pages.Count - 1);
pdf1.SaveToFile("merged.pdf");
pdf1.Close();
pdf2.Close();
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}Spire.PDF requires manually loading each document with new PdfDocument() + LoadFromFile(), then using InsertPageRange() to specify which pages to insert, and finally calling Close() on each document.
IronPDF uses the simpler PdfDocument.FromFile() pattern and a static PdfDocument.Merge() method that accepts multiple documents. No Close() calls needed. Learn more in our tutorials.
Example 3: Adding Text to a PDF
Before (Spire.PDF):
// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfPageBase page = pdf.Pages.Add();
PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 20);
PdfBrush brush = new PdfSolidBrush(Color.Black);
page.Canvas.DrawString("Hello from Spire.PDF!", font, brush, new PointF(50, 50));
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}// NuGet: Install-Package Spire.PDF
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System.Drawing;
using System;
class Program
{
static void Main()
{
PdfDocument pdf = new PdfDocument();
PdfPageBase page = pdf.Pages.Add();
PdfFont font = new PdfFont(PdfFontFamily.Helvetica, 20);
PdfBrush brush = new PdfSolidBrush(Color.Black);
page.Canvas.DrawString("Hello from Spire.PDF!", font, brush, new PointF(50, 50));
pdf.SaveToFile("output.pdf");
pdf.Close();
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body></body></html>");
var textStamper = new TextStamper()
{
Text = "Hello from IronPDF!",
FontSize = 20,
VerticalOffset = 50,
HorizontalOffset = 50
};
pdf.ApplyStamp(textStamper);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body></body></html>");
var textStamper = new TextStamper()
{
Text = "Hello from IronPDF!",
FontSize = 20,
VerticalOffset = 50,
HorizontalOffset = 50
};
pdf.ApplyStamp(textStamper);
pdf.SaveAs("output.pdf");
}
}Spire.PDF uses a canvas-based drawing model with PdfFont, PdfBrush, and page.Canvas.DrawString() to position text at specific coordinates using PointF.
IronPDF uses a TextStamper object with intuitive properties like Text, FontSize, VerticalOffset, and HorizontalOffset, then applies it with ApplyStamp(). This approach is more declarative and easier to maintain.
The Text-as-Images Problem
Why This Is Critical
When Spire.PDF converts HTML to PDF using image-based rendering, your documents lose essential functionality:
1. No Text Search: Users cannot use Ctrl+F to find text. Document management systems cannot index content.
2. No Text Selection/Copy: Users trying to copy a quote, reference, or data cannot select text—it's an image.
3. Accessibility Violations: Image-based PDFs fail WCAG 2.1 compliance, Section 508 compliance (US Government), ADA requirements, and screen reader compatibility.
4. Large File Sizes: Same content comparison shows Spire.PDF (image-based) produces files up to 16x larger than IronPDF (text-based).
Detection: Is Your PDF Image-Based?
Open your Spire.PDF-generated document and try these tests:
- Text Selection: Click and drag over text. If nothing highlights → IMAGE-BASED
- Ctrl+F Search: Search for any word on the page. If "No matches found" → IMAGE-BASED
- Copy/Paste: Select and copy text to notepad. If nothing pastes → IMAGE-BASED
The Internet Explorer Problem
Spire.PDF's Rendering Engine
Spire.PDF relies on Internet Explorer/Edge Legacy for HTML rendering in some environments. IE was deprecated in 2022, modern CSS doesn't work, JavaScript support is limited, and rendering is inconsistent across systems.
Modern CSS That Fails in Spire.PDF
<!-- This HTML renders incorrectly in Spire.PDF -->
<div style="display: flex; justify-content: space-between; gap: 20px;">
<div style="flex: 1;">Column 1</div>
<div style="flex: 1;">Column 2</div>
</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<!-- CSS Variables don't work -->
<style>
:root { --primary-color: #007bff; }
h1 { color: var(--primary-color); }
</style><!-- This HTML renders incorrectly in Spire.PDF -->
<div style="display: flex; justify-content: space-between; gap: 20px;">
<div style="flex: 1;">Column 1</div>
<div style="flex: 1;">Column 2</div>
</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>
<!-- CSS Variables don't work -->
<style>
:root { --primary-color: #007bff; }
h1 { color: var(--primary-color); }
</style>IronPDF uses modern Chromium rendering, so all these CSS features work correctly.
New Capabilities After Migration
After migrating to IronPDF, you gain capabilities that Spire.PDF cannot provide:
Selectable, Searchable Text
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Important Contract</h1>");
pdf.SaveAs("contract.pdf");
// Result:
// ✅ Text is fully selectable
// ✅ Text is searchable with Ctrl+F
// ✅ Text can be copied to clipboard
// ✅ Screen readers work perfectly
// ✅ File size is compact
// ✅ Zooming is crystal clearvar renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Important Contract</h1>");
pdf.SaveAs("contract.pdf");
// Result:
// ✅ Text is fully selectable
// ✅ Text is searchable with Ctrl+F
// ✅ Text can be copied to clipboard
// ✅ Screen readers work perfectly
// ✅ File size is compact
// ✅ Zooming is crystal clearModern CSS Support
var renderer = new ChromePdfRenderer();
var html = @"
<style>
:root { --primary: #007bff; }
.container { display: flex; gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
</style>
<div class='container'>
<div style='flex: 1; color: var(--primary)'>Column 1</div>
<div style='flex: 1'>Column 2</div>
</div>
<div class='grid'>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// All modern CSS features render correctly!var renderer = new ChromePdfRenderer();
var html = @"
<style>
:root { --primary: #007bff; }
.container { display: flex; gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(3, 1fr); }
</style>
<div class='container'>
<div style='flex: 1; color: var(--primary)'>Column 1</div>
<div style='flex: 1'>Column 2</div>
</div>
<div class='grid'>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// All modern CSS features render correctly!HTML-Based Watermarks
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.ApplyWatermark(@"
<div style='
font-size: 48px;
color: rgba(255, 0, 0, 0.5);
transform: rotate(-45deg);
'>DRAFT</div>");var pdf = renderer.RenderHtmlAsPdf(html);
pdf.ApplyWatermark(@"
<div style='
font-size: 48px;
color: rgba(255, 0, 0, 0.5);
transform: rotate(-45deg);
'>DRAFT</div>");Migration Checklist
Pre-Migration
- Inventory all Spire.PDF usages in codebase
- Test existing PDFs for text selectability (critical issue detection)
- Document
LoadFromHTML()calls (these are the priority to fix) - Obtain IronPDF license key from ironpdf.com
Code Updates
- Remove
Spire.PDFNuGet package (andFreeSpire.PDFif using free version) - Install
IronPdfNuGet package - Update namespace imports (
using Spire.Pdf;→using IronPdf;) - Replace
LoadFromHTML()withRenderHtmlAsPdf()(CRITICAL FIX) - Replace
new PdfDocument()+LoadFromFile()withPdfDocument.FromFile() - Replace
InsertPageRange()withPdfDocument.Merge() - Replace
Canvas.DrawString()withTextStamper+ApplyStamp() - Replace
SaveToFile()withSaveAs() - Remove all
Close()calls (not needed in IronPDF) - Add license initialization at application startup
Testing
- Verify text is selectable in generated PDFs (CRITICAL TEST)
- Verify CSS rendering improvements (Flexbox/Grid now work)
- Verify file sizes are smaller
- Test accessibility with screen readers
- Performance comparison






