Skip to footer content
MIGRATION GUIDES

How to Migrate from PrinceXML to IronPDF in C#

Migrating from PrinceXML to IronPDF transforms your PDF generation workflow from an external command-line process to a native .NET library. This guide provides a complete, step-by-step migration path that eliminates process management overhead, simplifies deployment, and provides extensive PDF manipulation capabilities beyond generation.

Why Migrate from PrinceXML to IronPDF

Understanding PrinceXML

PrinceXML is a sophisticated tool designed to excel at converting HTML content into print-perfect PDF documents through its dedicated support for CSS Paged Media specifications. This specialization allows PrinceXML to render documents with high fidelity to intended print designs—a valuable attribute for industries requiring detailed print styling, like publishing or legal documentation.

However, PrinceXML is not a .NET library and operates as a separate command-line tool, which may complicate integration for environments that prefer pure .NET solutions. Its reliance on a separate server process involves additional system resource management and potentially increased complexity for project deployments.

The External Process Problem

PrinceXML operates as a separate command-line executable that creates significant architectural challenges for .NET applications:

  1. Process Management Overhead: Must spawn, monitor, and terminate external processes.

  2. No Native .NET Integration: Communicate via stdin/stdout or temporary files.

  3. Deployment Complexity: Requires Prince installation on every server.

  4. Licensing Per Server: Each deployment needs a separate license ($495+).

  5. Error Handling Difficulty: Parse text output for error detection.

  6. No Async/Await: Blocking calls or complex async wrappers required.

  7. Path Dependencies: Must locate Prince executable on PATH or absolute path.

PrinceXML vs IronPDF Comparison

Aspect PrinceXML IronPDF
Architecture External Process Native .NET Library
Integration Command-line Direct API
Deployment Install on every server Single NuGet package
Error Handling Parse text output .NET exceptions
Async Support Manual wrappers Native async/await
PDF Manipulation Generation only Full manipulation (merge, split, edit)
Licensing Per server ($495+) Per developer
Updates Manual reinstall NuGet update
Debugging Difficult Full debugger support
Digital Signatures No Yes
Forms No Yes
Docker Support Complex Simple
Cloud Functions Difficult Easy

IronPDF provides an alternative with its .NET native capabilities, extending beyond mere HTML-to-PDF conversion to include advanced PDF manipulation tasks, such as editing, merging, and digital signatures. IronPDF's API is designed for simplicity and ease of use, letting developers perform conversions and manipulations with minimal boilerplate code.

For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF's seamless deployment requires no external dependencies or server processes and thus eases the burden of integration into the .NET framework.


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

# Install IronPDF
dotnet add package IronPdf

# Remove Prince wrapper if using one
dotnet remove package PrinceXMLWrapper
# Install IronPDF
dotnet add package IronPdf

# Remove Prince wrapper if using one
dotnet remove package PrinceXMLWrapper
SHELL

License Configuration

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

Search for PrinceXML Usage

# Find Prince process calls
grep -r "prince" --include="*.cs" .
grep -r "Process.Start" --include="*.cs" . | grep -i prince
grep -r "@page" --include="*.css" .
grep -r "prince-" --include="*.css" .
# Find Prince process calls
grep -r "prince" --include="*.cs" .
grep -r "Process.Start" --include="*.cs" . | grep -i prince
grep -r "@page" --include="*.css" .
grep -r "prince-" --include="*.css" .
SHELL

Complete API Reference

Namespace Changes

// Before: PrinceXML
using PrinceXMLWrapper;
using System.Diagnostics;
using System.IO;

// After: IronPDF
using IronPdf;
// Before: PrinceXML
using PrinceXMLWrapper;
using System.Diagnostics;
using System.IO;

// After: IronPDF
using IronPdf;
' Before: PrinceXML
Imports PrinceXMLWrapper
Imports System.Diagnostics
Imports System.IO

' After: IronPDF
Imports IronPdf
$vbLabelText   $csharpLabel

Command-Line to Method Mapping

Prince Command IronPDF Equivalent
prince input.html -o output.pdf renderer.RenderHtmlFileAsPdf("input.html").SaveAs("output.pdf")
prince --style=custom.css input.html Include CSS in HTML or use RenderingOptions
prince --javascript renderer.RenderingOptions.EnableJavaScript = true
prince --no-javascript renderer.RenderingOptions.EnableJavaScript = false
prince --page-size=Letter renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
prince --page-margin=1in renderer.RenderingOptions.MarginTop = 72 (72 points = 1 inch)
prince --encrypt pdf.SecuritySettings.OwnerPassword = "..."
prince --user-password=pw pdf.SecuritySettings.UserPassword = "pw"
prince --disallow-print pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint
prince --disallow-copy pdf.SecuritySettings.AllowUserCopyPasteContent = false
prince --baseurl=http://... renderer.RenderingOptions.BaseUrl = new Uri("http://...")
prince --media=print renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
prince --media=screen renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen

CSS @page to RenderingOptions Mapping

CSS @page Property IronPDF Equivalent
size: A4 PaperSize = PdfPaperSize.A4
size: Letter PaperSize = PdfPaperSize.Letter
size: A4 landscape PaperSize = PdfPaperSize.A4 + PaperOrientation = Landscape
margin: 2cm MarginTop/Bottom/Left/Right = 56
margin-top: 1in MarginTop = 72
@top-center { content: "..." } HtmlHeader with centered div
@bottom-right { content: counter(page) } HtmlFooter with {page} placeholder

Page Size Conversions

Size Points Millimeters
Letter 612 x 792 216 x 279
A4 595 x 842 210 x 297
Legal 612 x 1008 216 x 356
1 inch 72 25.4
1 cm 28.35 10

Code Migration Examples

Example 1: HTML File to PDF Conversion

Before (PrinceXML):

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

class Program
{
    static void Main()
    {
        Prince prince = new Prince("C:\\Program Files\\Prince\\engine\\bin\\prince.exe");
        prince.Convert("input.html", "output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package PrinceXMLWrapper
using PrinceXMLWrapper;
using System;

class Program
{
    static void Main()
    {
        Prince prince = new Prince("C:\\Program Files\\Prince\\engine\\bin\\prince.exe");
        prince.Convert("input.html", "output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
Imports PrinceXMLWrapper
Imports System

Module Program
    Sub Main()
        Dim prince As New Prince("C:\Program Files\Prince\engine\bin\prince.exe")
        prince.Convert("input.html", "output.pdf")
        Console.WriteLine("PDF created successfully")
    End Sub
End Module
$vbLabelText   $csharpLabel

After (IronPDF):

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        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 pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
        pdf.SaveAs("output.pdf")
        Console.WriteLine("PDF created successfully")
    End Sub
End Class
$vbLabelText   $csharpLabel

This example demonstrates the fundamental architectural difference. PrinceXML requires instantiating a Prince object with the full path to the executable ("C:\\Program Files\\Prince\\engine\\bin\\prince.exe"), then calling Convert() with input and output paths.

IronPDF eliminates path dependencies entirely: create a ChromePdfRenderer, call RenderHtmlFileAsPdf() with the HTML file path, and SaveAs() to write the result. No executable paths, no process management, no path dependencies. See the HTML to PDF documentation for comprehensive examples.

Example 2: URL to PDF Conversion with Options

Before (PrinceXML):

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

class Program
{
    static void Main()
    {
        Prince prince = new Prince("C:\\Program Files\\Prince\\engine\\bin\\prince.exe");
        prince.SetJavaScript(true);
        prince.SetEncrypt(true);
        prince.SetPDFTitle("Website Export");
        prince.Convert("https://example.com", "webpage.pdf");
        Console.WriteLine("URL converted to PDF");
    }
}
// NuGet: Install-Package PrinceXMLWrapper
using PrinceXMLWrapper;
using System;

class Program
{
    static void Main()
    {
        Prince prince = new Prince("C:\\Program Files\\Prince\\engine\\bin\\prince.exe");
        prince.SetJavaScript(true);
        prince.SetEncrypt(true);
        prince.SetPDFTitle("Website Export");
        prince.Convert("https://example.com", "webpage.pdf");
        Console.WriteLine("URL converted to PDF");
    }
}
Imports PrinceXMLWrapper
Imports System

Class Program
    Shared Sub Main()
        Dim prince As New Prince("C:\Program Files\Prince\engine\bin\prince.exe")
        prince.SetJavaScript(True)
        prince.SetEncrypt(True)
        prince.SetPDFTitle("Website Export")
        prince.Convert("https://example.com", "webpage.pdf")
        Console.WriteLine("URL converted to PDF")
    End Sub
End Class
$vbLabelText   $csharpLabel

After (IronPDF):

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.EnableJavaScript = true;
        renderer.RenderingOptions.PdfTitle = "Website Export";

        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.Encrypt("password");
        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("URL converted to PDF");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.EnableJavaScript = true;
        renderer.RenderingOptions.PdfTitle = "Website Export";

        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.Encrypt("password");
        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("URL converted to PDF");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        renderer.RenderingOptions.EnableJavaScript = True
        renderer.RenderingOptions.PdfTitle = "Website Export"

        Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
        pdf.Encrypt("password")
        pdf.SaveAs("webpage.pdf")
        Console.WriteLine("URL converted to PDF")
    End Sub
End Class
$vbLabelText   $csharpLabel

This example shows how PrinceXML options map to IronPDF properties. PrinceXML uses setter methods (SetJavaScript(), SetEncrypt(), SetPDFTitle()) before conversion. IronPDF uses RenderingOptions properties for pre-render settings, and post-render methods like Encrypt() on the PdfDocument object.

Key mappings:

  • prince.SetJavaScript(true)renderer.RenderingOptions.EnableJavaScript = true
  • prince.SetPDFTitle("...")renderer.RenderingOptions.PdfTitle = "..."
  • prince.SetEncrypt(true)pdf.Encrypt("password") (IronPDF requires a password)

Learn more in our tutorials.

Example 3: HTML String to PDF Conversion

Before (PrinceXML):

// NuGet: Install-Package PrinceXMLWrapper
using PrinceXMLWrapper;
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string html = "<html><head><style>body { font-family: Arial; color: blue; }</style></head><body><h1>Hello World</h1></body></html>";
        File.WriteAllText("temp.html", html);

        Prince prince = new Prince("C:\\Program Files\\Prince\\engine\\bin\\prince.exe");
        prince.Convert("temp.html", "styled-output.pdf");
        Console.WriteLine("Styled PDF created");
    }
}
// NuGet: Install-Package PrinceXMLWrapper
using PrinceXMLWrapper;
using System;
using System.IO;

class Program
{
    static void Main()
    {
        string html = "<html><head><style>body { font-family: Arial; color: blue; }</style></head><body><h1>Hello World</h1></body></html>";
        File.WriteAllText("temp.html", html);

        Prince prince = new Prince("C:\\Program Files\\Prince\\engine\\bin\\prince.exe");
        prince.Convert("temp.html", "styled-output.pdf");
        Console.WriteLine("Styled PDF created");
    }
}
Imports PrinceXMLWrapper
Imports System
Imports System.IO

Module Program
    Sub Main()
        Dim html As String = "<html><head><style>body { font-family: Arial; color: blue; }</style></head><body><h1>Hello World</h1></body></html>"
        File.WriteAllText("temp.html", html)

        Dim prince As New Prince("C:\Program Files\Prince\engine\bin\prince.exe")
        prince.Convert("temp.html", "styled-output.pdf")
        Console.WriteLine("Styled PDF created")
    End Sub
End Module
$vbLabelText   $csharpLabel

After (IronPDF):

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

class Program
{
    static void Main()
    {
        string html = "<html><head><style>body { font-family: Arial; color: blue; }</style></head><body><h1>Hello World</h1></body></html>";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("styled-output.pdf");
        Console.WriteLine("Styled PDF created");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        string html = "<html><head><style>body { font-family: Arial; color: blue; }</style></head><body><h1>Hello World</h1></body></html>";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("styled-output.pdf");
        Console.WriteLine("Styled PDF created");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim html As String = "<html><head><style>body { font-family: Arial; color: blue; }</style></head><body><h1>Hello World</h1></body></html>"

        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf(html)
        pdf.SaveAs("styled-output.pdf")
        Console.WriteLine("Styled PDF created")
    End Sub
End Class
$vbLabelText   $csharpLabel

This example highlights a critical difference: PrinceXML requires file input, so you must create a temporary file (File.WriteAllText("temp.html", html)) before conversion. IronPDF's RenderHtmlAsPdf() accepts HTML strings directly—no temporary files, no cleanup code, no disk I/O overhead.


Migrating CSS Paged Media

While PrinceXML's CSS Paged Media support is powerful, it creates vendor lock-in with Prince-specific CSS that won't work elsewhere:

PrinceXML CSS:

@page {
    size: A4;
    margin: 2cm;
    @top-center {
        content: "Document Title";
    }
    @bottom-right {
        content: counter(page);
    }
}

/* Prince-specific extensions */
prince-pdf-page-label: "Chapter " counter(chapter);
prince-pdf-destination: attr(id);

IronPDF C# (equivalent):

renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 56;    // ~2cm
renderer.RenderingOptions.MarginBottom = 56;
renderer.RenderingOptions.MarginLeft = 56;
renderer.RenderingOptions.MarginRight = 56;

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:center;'>Document Title</div>",
    MaxHeight = 40
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:right;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 56;    // ~2cm
renderer.RenderingOptions.MarginBottom = 56;
renderer.RenderingOptions.MarginLeft = 56;
renderer.RenderingOptions.MarginRight = 56;

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:center;'>Document Title</div>",
    MaxHeight = 40
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:right;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 56    ' ~2cm
renderer.RenderingOptions.MarginBottom = 56
renderer.RenderingOptions.MarginLeft = 56
renderer.RenderingOptions.MarginRight = 56

renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
    .HtmlFragment = "<div style='text-align:center;'>Document Title</div>",
    .MaxHeight = 40
}

renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "<div style='text-align:right;'>Page {page} of {total-pages}</div>",
    .MaxHeight = 25
}
$vbLabelText   $csharpLabel

Common CSS Migration Issues

Issue 1: CSS @page Not Working

IronPDF uses Chromium, which has limited @page support. Convert CSS rules to RenderingOptions.

Issue 2: Page Margin Boxes Missing

CSS margin boxes (@top-center, @bottom-right) are Prince-specific. Use HtmlHeader/HtmlFooter instead.

Issue 3: string-set/content Not Working

The string-set CSS property is Prince-specific. Use {html-title} placeholder from the <title> tag:

<title>Chapter 1: Introduction</title>
<title>Chapter 1: Introduction</title>
HTML
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = "<div>{html-title}</div>"
};
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = "<div>{html-title}</div>"
};
$vbLabelText   $csharpLabel

Issue 4: counter(pages) Incorrect

Use IronPDF's {total-pages} placeholder instead of CSS counters.


Performance Comparison

Operation PrinceXML IronPDF
Simple HTML ~400ms ~300ms
Complex CSS ~600ms ~400ms
JavaScript pages Limited ~500ms
Large documents ~1500ms ~1000ms
Concurrent (10) ~4000ms ~1500ms
Startup overhead ~200ms ~50ms

New Capabilities After Migration

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

PDF Merging

var pdf1 = PdfDocument.FromFile("chapter1.pdf");
var pdf2 = PdfDocument.FromFile("chapter2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("complete_book.pdf");
var pdf1 = PdfDocument.FromFile("chapter1.pdf");
var pdf2 = PdfDocument.FromFile("chapter2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("complete_book.pdf");
Dim pdf1 = PdfDocument.FromFile("chapter1.pdf")
Dim pdf2 = PdfDocument.FromFile("chapter2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("complete_book.pdf")
$vbLabelText   $csharpLabel

Watermarks

pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.3;'>DRAFT</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Digital Signatures

var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
Dim signature = New PdfSignature("certificate.pfx", "password")
pdf.Sign(signature)
$vbLabelText   $csharpLabel

Form Filling

var pdf = PdfDocument.FromFile("form.pdf");
pdf.Form.GetFieldByName("Name").Value = "John Doe";
pdf.SaveAs("filled_form.pdf");
var pdf = PdfDocument.FromFile("form.pdf");
pdf.Form.GetFieldByName("Name").Value = "John Doe";
pdf.SaveAs("filled_form.pdf");
Dim pdf = PdfDocument.FromFile("form.pdf")
pdf.Form.GetFieldByName("Name").Value = "John Doe"
pdf.SaveAs("filled_form.pdf")
$vbLabelText   $csharpLabel

Feature Comparison Summary

Feature PrinceXML IronPDF
Native .NET No Yes
External Process Required No
Async Support Manual wrapping Native async/await
CSS Paged Media Supported Via RenderingOptions
CSS Grid Yes Yes
Flexbox Yes Yes
JavaScript Limited Full ES2024
Generation Yes Yes
Merge No Yes
Split No Yes
Edit No Yes
Watermarks CSS only HTML/CSS + API
Digital Signatures No Yes
PDF/A Yes Yes
Encryption Yes Yes
Forms No Yes
NuGet Package No Yes
Server Install Required No

Migration Checklist

Pre-Migration

  • Identify all Prince command-line invocations
  • Document CSS @page rules used
  • List Prince-specific CSS properties (prince-*, string-set)
  • Note any Prince JavaScript functions
  • Identify PDF features used (encryption, metadata)
  • Obtain IronPDF license key from ironpdf.com

Code Changes

  • Remove PrinceXMLWrapper NuGet package
  • Install IronPdf NuGet package
  • Update namespace imports
  • Replace Prince instantiation with ChromePdfRenderer
  • Replace prince.Convert() with RenderHtmlFileAsPdf() or RenderHtmlAsPdf()
  • Convert setter methods to RenderingOptions properties
  • Migrate @page CSS to RenderingOptions
  • Replace margin boxes with HtmlHeader/HtmlFooter
  • Convert CSS counters to {page}/{total-pages} placeholders
  • Remove temporary file handling for HTML strings
  • Add license initialization at application startup

Post-Migration

  • Test HTML file conversion
  • Test HTML string conversion
  • Test URL conversion
  • Verify page sizes match
  • Verify margins match
  • Test headers and footers
  • Verify page numbers
  • Test encryption/security
  • Remove Prince installation from servers
  • Update deployment scripts

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

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me