Skip to footer content
MIGRATION GUIDES

How to Migrate from iText to IronPDF in C#

Migrating from iText to IronPDF transforms your .NET PDF workflow from a programmatic API requiring manual construction of Paragraph, Table, and Cell objects to a modern HTML-first approach with full CSS3 and JavaScript support. This guide provides a comprehensive, step-by-step migration path that eliminates AGPL licensing concerns and the need for separate pdfHTML add-ons for professional .NET developers.

Why Migrate from iText to IronPDF

The AGPL License Trap

iText presents serious legal and business risks for commercial applications that many development teams discover too late:

  1. AGPL Viral License: If you use iText in a web application, the AGPL requires you to open-source your ENTIRE application—not just the PDF code, but your entire codebase. This is a non-starter for most commercial software.

  2. No Perpetual License: iText has eliminated perpetual licensing, forcing annual subscription renewals that increase total cost of ownership.

  3. pdfHTML Add-On Cost: HTML-to-PDF functionality requires the pdfHTML add-on, sold separately at additional cost on top of the base license.

  4. Complex Licensing Audits: Enterprise deployments face licensing complexity and audit risk that can delay projects and create legal exposure.

  5. Programmatic-Only API: iText requires manual low-level PDF construction with Paragraph, Table, Cell objects—tedious and error-prone for complex layouts.

  6. Limited Modern Web Rendering: Even with pdfHTML, complex CSS and JavaScript content requires significant additional effort.

iText vs IronPDF Comparison

FeatureiText 7 / iTextSharpIronPDF
LicenseAGPL (viral) or expensive subscriptionCommercial, perpetual option
HTML-to-PDFSeparate pdfHTML add-onBuilt-in Chromium renderer
CSS SupportBasic CSSFull CSS3, Flexbox, Grid
JavaScriptNoneFull execution
API ParadigmProgrammatic (Paragraph, Table, Cell)HTML-first with CSS
Learning CurveSteep (PDF coordinate system)Web developer friendly
Open Source RiskMust open-source web appsNo viral requirements
Pricing ModelSubscription onlyPerpetual or subscription

For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a future-proof foundation with its HTML-first approach that leverages web development skills your team already has.


Migration Complexity Assessment

Estimated Effort by Feature

FeatureMigration ComplexityNotes
HTML to PDFVery LowDirect method replacement
Merge PDFsLowSimpler API
Text and ImagesLowHTML replaces programmatic
TablesMediumHTML tables replace iText Table class
Headers/FootersMediumEvent handlers → HTML templates
Security/EncryptionLowProperty-based API

Paradigm Shift

The fundamental shift in this iText migration is from programmatic PDF construction to HTML-first rendering:

iText:    PdfWriter → PdfDocument → Document → Add(Paragraph) → Add(Table)
IronPDF:  ChromePdfRenderer → RenderHtmlAsPdf(htmlString) → SaveAs()

This paradigm shift is liberating: instead of learning iText's object model, you use HTML and CSS skills that web developers already possess.


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 iText packages
dotnet remove package itext7
dotnet remove package itext7.pdfhtml
dotnet remove package itextsharp

# Install IronPDF
dotnet add package IronPdf
# Remove iText packages
dotnet remove package itext7
dotnet remove package itext7.pdfhtml
dotnet remove package itextsharp

# Install IronPDF
dotnet add package IronPdf
SHELL

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 iText Usage

# Find all iText references
grep -r "using iText\|using iTextSharp" --include="*.cs" .
grep -r "PdfWriter\|PdfDocument\|Document\|Paragraph\|Table\|Cell" --include="*.cs" .
grep -r "HtmlConverter\|ConverterProperties" --include="*.cs" .
# Find all iText references
grep -r "using iText\|using iTextSharp" --include="*.cs" .
grep -r "PdfWriter\|PdfDocument\|Document\|Paragraph\|Table\|Cell" --include="*.cs" .
grep -r "HtmlConverter\|ConverterProperties" --include="*.cs" .
SHELL

Complete API Reference

Class Mappings

iText 7 ClassiTextSharp ClassIronPDF Equivalent
PdfWriterPdfWriterChromePdfRenderer
PdfDocumentDocumentPdfDocument
DocumentDocumentChromePdfRenderer.RenderHtmlAsPdf()
ParagraphParagraphHTML <p>, <h1>, etc.
TablePdfPTableHTML <table>
CellPdfPCellHTML <td>, <th>
ImageImageHTML <img>
PdfReaderPdfReaderPdfDocument.FromFile()
PdfMergerN/APdfDocument.Merge()

Namespace Mappings

iText 7 NamespaceIronPDF Equivalent
iText.Kernel.PdfIronPdf
iText.LayoutIronPdf
iText.Layout.ElementUse HTML elements
iText.Html2PdfIronPdf (built-in)
iText.IO.ImageUse HTML <img>
iText.Kernel.UtilsIronPdf

Code Migration Examples

Example 1: HTML to PDF Conversion

Before (iText 7):

// NuGet: Install-Package itext7
using iText.Html2pdf;
using System.IO;

class Program
{
    static void Main()
    {
        string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";
        string outputPath = "output.pdf";

        using (FileStream fs = new FileStream(outputPath, FileMode.Create))
        {
            HtmlConverter.ConvertToPdf(html, fs);
        }
    }
}
// NuGet: Install-Package itext7
using iText.Html2pdf;
using System.IO;

class Program
{
    static void Main()
    {
        string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";
        string outputPath = "output.pdf";

        using (FileStream fs = new FileStream(outputPath, FileMode.Create))
        {
            HtmlConverter.ConvertToPdf(html, fs);
        }
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";

        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 = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>";

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

The iText approach requires the separate iText.Html2pdf package (pdfHTML add-on, sold separately), creating a FileStream, and wrapping everything in using statements for proper disposal. The HtmlConverter.ConvertToPdf() method writes directly to the stream.

IronPDF's approach is cleaner: create a ChromePdfRenderer, call RenderHtmlAsPdf() with your HTML string, and call SaveAs() on the resulting PdfDocument. No separate packages, no stream management, and the Chromium rendering engine provides superior CSS3 and JavaScript support. See the HTML to PDF documentation for additional rendering options.

Example 2: Merge Multiple PDFs

Before (iText 7):

// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Kernel.Utils;
using System.IO;

class Program
{
    static void Main()
    {
        string outputPath = "merged.pdf";
        string[] inputFiles = { "document1.pdf", "document2.pdf", "document3.pdf" };

        using (PdfWriter writer = new PdfWriter(outputPath))
        using (PdfDocument pdfDoc = new PdfDocument(writer))
        {
            PdfMerger merger = new PdfMerger(pdfDoc);

            foreach (string file in inputFiles)
            {
                using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
                {
                    merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
                }
            }
        }
    }
}
// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Kernel.Utils;
using System.IO;

class Program
{
    static void Main()
    {
        string outputPath = "merged.pdf";
        string[] inputFiles = { "document1.pdf", "document2.pdf", "document3.pdf" };

        using (PdfWriter writer = new PdfWriter(outputPath))
        using (PdfDocument pdfDoc = new PdfDocument(writer))
        {
            PdfMerger merger = new PdfMerger(pdfDoc);

            foreach (string file in inputFiles)
            {
                using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
                {
                    merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
                }
            }
        }
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdfDocuments = new List<PdfDocument>
        {
            PdfDocument.FromFile("document1.pdf"),
            PdfDocument.FromFile("document2.pdf"),
            PdfDocument.FromFile("document3.pdf")
        };

        var merged = PdfDocument.Merge(pdfDocuments);
        merged.SaveAs("merged.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdfDocuments = new List<PdfDocument>
        {
            PdfDocument.FromFile("document1.pdf"),
            PdfDocument.FromFile("document2.pdf"),
            PdfDocument.FromFile("document3.pdf")
        };

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

The iText merge operation requires significant boilerplate: creating a PdfWriter for output, wrapping it in a PdfDocument, creating a PdfMerger, then iterating through source files with nested using statements for each PdfDocument and PdfReader. You must also specify page ranges with merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages()).

IronPDF reduces this to three steps: load documents with PdfDocument.FromFile(), call the static PdfDocument.Merge() method with the list, and save. The entire merge operation becomes readable and maintainable. Learn more about merging and splitting PDFs.

Example 3: Create PDF with Text and Images

Before (iText 7):

// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.IO.Image;

class Program
{
    static void Main()
    {
        string outputPath = "document.pdf";

        using (PdfWriter writer = new PdfWriter(outputPath))
        using (PdfDocument pdf = new PdfDocument(writer))
        using (Document document = new Document(pdf))
        {
            document.Add(new Paragraph("Sample PDF Document"));
            document.Add(new Paragraph("This document contains text and an image."));

            Image img = new Image(ImageDataFactory.Create("image.jpg"));
            img.SetWidth(200);
            document.Add(img);
        }
    }
}
// NuGet: Install-Package itext7
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.IO.Image;

class Program
{
    static void Main()
    {
        string outputPath = "document.pdf";

        using (PdfWriter writer = new PdfWriter(outputPath))
        using (PdfDocument pdf = new PdfDocument(writer))
        using (Document document = new Document(pdf))
        {
            document.Add(new Paragraph("Sample PDF Document"));
            document.Add(new Paragraph("This document contains text and an image."));

            Image img = new Image(ImageDataFactory.Create("image.jpg"));
            img.SetWidth(200);
            document.Add(img);
        }
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        string html = @"
            <h1>Sample PDF Document</h1>
            <p>This document contains text and an image.</p>
            <img src='image.jpg' width='200' />";

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        string html = @"
            <h1>Sample PDF Document</h1>
            <p>This document contains text and an image.</p>
            <img src='image.jpg' width='200' />";

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

This example illustrates the paradigm shift most clearly. iText requires:

  • Triple-nested using statements (PdfWriter, PdfDocument, Document)
  • Creating Paragraph objects for each text element with new Paragraph()
  • Using ImageDataFactory.Create() to load images
  • Creating an Image object and calling SetWidth() separately
  • Calling document.Add() for each element

IronPDF uses standard HTML: <h1> for headings, <p> for paragraphs, and <img> for images with a width attribute. Web developers can leverage their existing skills immediately, and designers can style documents using CSS they already know.


Critical Migration Notes

Paradigm Shift: Programmatic to HTML-First

The most significant change in this iText migration is conceptual. iText builds PDFs programmatically:

// iText approach
document.Add(new Paragraph("Title")
    .SetTextAlignment(TextAlignment.CENTER)
    .SetFontSize(24)
    .SetBold());

var table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth();
table.AddHeaderCell(new Cell().Add(new Paragraph("ID")));
table.AddHeaderCell(new Cell().Add(new Paragraph("Name")));
// ... many more lines
// iText approach
document.Add(new Paragraph("Title")
    .SetTextAlignment(TextAlignment.CENTER)
    .SetFontSize(24)
    .SetBold());

var table = new Table(UnitValue.CreatePercentArray(3)).UseAllAvailableWidth();
table.AddHeaderCell(new Cell().Add(new Paragraph("ID")));
table.AddHeaderCell(new Cell().Add(new Paragraph("Name")));
// ... many more lines
$vbLabelText   $csharpLabel

IronPDF uses HTML and CSS:

// IronPDF approach
string html = @"
    <style>
        h1 { text-align: center; font-size: 24px; font-weight: bold; }
        table { width: 100%; border-collapse: collapse; }
        th { background-color: #4CAF50; color: white; padding: 8px; }
    </style>
    <h1>Title</h1>
    <table>
        <tr><th>ID</th><th>Name</th></tr>
    </table>";

var pdf = renderer.RenderHtmlAsPdf(html);
// IronPDF approach
string html = @"
    <style>
        h1 { text-align: center; font-size: 24px; font-weight: bold; }
        table { width: 100%; border-collapse: collapse; }
        th { background-color: #4CAF50; color: white; padding: 8px; }
    </style>
    <h1>Title</h1>
    <table>
        <tr><th>ID</th><th>Name</th></tr>
    </table>";

var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

AGPL License Eliminated

iText's AGPL license requires open-sourcing your entire web application or purchasing an expensive commercial license. IronPDF's commercial license allows deployment in proprietary software without viral licensing requirements.

No pdfHTML Add-On Required

iText requires the separate pdfHTML add-on for HTML-to-PDF conversion, sold at additional cost. IronPDF includes full Chromium-based HTML rendering in the base package.

Method Replacement Patterns

iText PatternIronPDF Replacement
SetTextAlignment(TextAlignment.CENTER)CSS text-align: center
SetFontSize(24)CSS font-size: 24px
SetBold()CSS font-weight: bold
new Table(3)HTML <table>
AddHeaderCell(new Cell().Add(new Paragraph()))HTML <th>
AddCell(new Cell().Add(new Paragraph()))HTML <td>

Troubleshooting

Issue 1: PdfWriter/Document Pattern

Problem: Code uses the PdfWriterPdfDocumentDocument nesting pattern.

Solution: Replace with ChromePdfRenderer:

// Delete this iText pattern:
// using (var writer = new PdfWriter(outputPath))
// using (var pdfDoc = new PdfDocument(writer))
// using (var document = new Document(pdfDoc))

// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
// Delete this iText pattern:
// using (var writer = new PdfWriter(outputPath))
// using (var pdfDoc = new PdfDocument(writer))
// using (var document = new Document(pdfDoc))

// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
$vbLabelText   $csharpLabel

Issue 2: HtmlConverter Not Found

Problem: Code uses iText.Html2pdf.HtmlConverter which requires the pdfHTML add-on.

Solution: Use IronPDF's built-in HTML rendering:

// iText (requires pdfHTML add-on)
HtmlConverter.ConvertToPdf(html, fileStream);

// IronPDF (built-in)
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
// iText (requires pdfHTML add-on)
HtmlConverter.ConvertToPdf(html, fileStream);

// IronPDF (built-in)
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
$vbLabelText   $csharpLabel

Issue 3: PdfMerger Complexity

Problem: iText's PdfMerger requires nested readers and page range specification.

Solution: Use IronPDF's static merge method:

// iText merger pattern (delete this)
// using (PdfDocument pdfDoc = new PdfDocument(writer))
// {
//     PdfMerger merger = new PdfMerger(pdfDoc);
//     foreach (string file in inputFiles)
//     {
//         using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
//         {
//             merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
//         }
//     }
// }

// IronPDF (simple)
var merged = PdfDocument.Merge(pdfDocuments);
merged.SaveAs("merged.pdf");
// iText merger pattern (delete this)
// using (PdfDocument pdfDoc = new PdfDocument(writer))
// {
//     PdfMerger merger = new PdfMerger(pdfDoc);
//     foreach (string file in inputFiles)
//     {
//         using (PdfDocument sourcePdf = new PdfDocument(new PdfReader(file)))
//         {
//             merger.Merge(sourcePdf, 1, sourcePdf.GetNumberOfPages());
//         }
//     }
// }

// IronPDF (simple)
var merged = PdfDocument.Merge(pdfDocuments);
merged.SaveAs("merged.pdf");
$vbLabelText   $csharpLabel

Migration Checklist

Pre-Migration

  • Inventory all iText API calls in codebase
  • Identify programmatic PDF construction patterns (Paragraph, Table, Cell)
  • Document HtmlConverter usage (pdfHTML add-on)
  • Assess AGPL compliance risk
  • Obtain IronPDF license key

Code Migration

  • Remove iText NuGet packages: dotnet remove package itext7
  • Install IronPdf NuGet package: dotnet add package IronPdf
  • Update namespace imports (using iText.*using IronPdf)
  • Replace PdfWriter/Document pattern with ChromePdfRenderer
  • Convert Paragraph/Table/Cell to HTML elements
  • Replace HtmlConverter.ConvertToPdf() with RenderHtmlAsPdf()
  • Update merge operations to PdfDocument.Merge()
  • Add license key initialization at startup

Testing

  • Test all PDF generation paths
  • Verify visual output matches expectations
  • Test with complex HTML/CSS content
  • Benchmark performance

Post-Migration

  • Remove iText license files and references
  • Update documentation
  • Cancel iText subscription (if applicable)
  • Archive legacy iText code

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