Skip to footer content
MIGRATION GUIDES

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

IssueImpactIronPDF Solution
Text rendered as imagesPDFs not searchable, not accessible, can't copy textReal text rendering
Internet Explorer dependencyOutdated rendering, security risksModern Chromium engine
Font embedding failuresDocuments look wrong on other systemsReliable font handling
Large deployment footprintHigh memory usage, slow startupEfficient deployment
Limited CSS supportModern layouts don't render correctlyFull 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

FeatureSpire.PDFIronPDF
HTML to PDF RenderingText rendered as imagesTrue text rendering (selectable and searchable)
Rendering EngineInternet Explorer dependent on some systemsChromium-based, modern web standards compliant
Font HandlingKnown issues with font embeddingReliable and robust font handling
CSS3 SupportLimitedFull
Flexbox/GridNot supportedFull support
JavaScriptLimitedFull ES6+
PDF AccessibilityPoor (image-based)Excellent
API DesignComplexSimple and intuitive
Deployment FootprintLargeModerate
LicensingFreemium/CommercialCommercial

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

  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 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 IronPdf
SHELL

License Configuration

// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

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;
$vbLabelText   $csharpLabel

Core API Mappings

Spire.PDFIronPDFNotes
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 neededUses dispose pattern
pdf.Pages.Add()renderer.RenderHtmlAsPdf()Create page from HTML
pdf.InsertPageRange()PdfDocument.Merge()Merge PDFs
page.Canvas.DrawString()TextStamper + ApplyStamp()Add text
PdfFontCSS styling in HTMLFont configuration
PdfBrushCSS styling in HTMLColor/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();
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
$vbLabelText   $csharpLabel

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();
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
$vbLabelText   $csharpLabel

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();
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
$vbLabelText   $csharpLabel

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:

  1. Text Selection: Click and drag over text. If nothing highlights → IMAGE-BASED
  2. Ctrl+F Search: Search for any word on the page. If "No matches found" → IMAGE-BASED
  3. 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>
HTML

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 clear
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 clear
$vbLabelText   $csharpLabel

Modern 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!
$vbLabelText   $csharpLabel

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>");
$vbLabelText   $csharpLabel

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.PDF NuGet package (and FreeSpire.PDF if using free version)
  • Install IronPdf NuGet package
  • Update namespace imports (using Spire.Pdf;using IronPdf;)
  • Replace LoadFromHTML() with RenderHtmlAsPdf() (CRITICAL FIX)
  • Replace new PdfDocument() + LoadFromFile() with PdfDocument.FromFile()
  • Replace InsertPageRange() with PdfDocument.Merge()
  • Replace Canvas.DrawString() with TextStamper + ApplyStamp()
  • Replace SaveToFile() with SaveAs()
  • 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

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