Skip to footer content
MIGRATION GUIDES

How to Migrate from PDFreactor to IronPDF in C#

Migrating from PDFreactor to IronPDF eliminates Java dependencies and server infrastructure while providing equivalent HTML-to-PDF conversion capabilities through a native .NET library. This guide provides a complete, step-by-step migration path that replaces your Java-based server architecture with an in-process library that integrates seamlessly into .NET applications.

Why Migrate from PDFreactor to IronPDF

Understanding PDFreactor

PDFreactor is a powerful HTML-to-PDF conversion server that integrates across various platforms. As a commercial solution, PDFreactor leverages its proprietary technology to convert HTML and CSS content into high-quality PDF documents. Among its notable attributes, PDFreactor supports a wide array of CSS properties which makes it a strong candidate for complex layout rendering.

However, PDFreactor's reliance on Java presents certain challenges in .NET environments where its non-native nature may complicate deployment and integration. Its dependency on Java creates extra overhead in .NET applications, often requiring additional integration work.

The Java Dependency Problem

PDFreactor's architecture creates several challenges in .NET environments:

  1. Java Runtime Required: Requires JRE/JDK installation on all servers.

  2. Server Architecture: Runs as a separate service requiring additional infrastructure. As a server-based solution, PDFreactor requires REST API calls for every conversion.

  3. Complex Deployment: Managing Java dependencies in a primarily .NET ecosystem can complicate the setup and increase maintenance costs. Two runtimes (Java + .NET) to manage in CI/CD pipelines.

  4. Inter-Process Communication: REST API or socket communication adds latency. Every PDF conversion requires HTTP round-trip to server.

  5. Separate License Management: License bound to server instance, not application. Per-server licensing tied to Java service instance.

  6. Resource Isolation: Separate process memory and CPU management. Additional server to monitor, scale, and maintain.

PDFreactor vs IronPDF Comparison

Feature/AspectPDFreactorIronPDF
Native .NET LibraryNo (Java-based)Yes
RuntimeJava (external server)Native .NET (in-process)
ArchitectureREST API serviceNuGet library
DeploymentJava + server configSingle NuGet package
DependenciesJRE + HTTP clientSelf-contained
LatencyNetwork round-tripDirect method calls
Cross-Platform CapabilityYes (Java-dependent)Yes (Bundled Chromium)
CSS SupportAdvanced support for CSS3, CSS Paged MediaComprehensive HTML5/CSS3 support
Deployment ComplexityMore complex due to JavaSimple, directly integrates with .NET
PDF Manipulation FeaturesBasic (Generation only)Extensive, including merge, split, edit, and annotate

In contrast to PDFreactor, IronPDF presents itself as a native .NET library, specifically designed to integrate seamlessly into .NET projects without external dependencies like Java. IronPDF uses a bundled Chromium rendering engine, allowing it to convert HTML to PDF with just a few lines of code.

For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a native .NET solution that eliminates Java server complexity while offering comprehensive PDF lifecycle management.


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 PDFreactor NuGet packages
dotnet remove package PDFreactor.NET
dotnet remove package PDFreactor.Native.Windows.x64

# Stop PDFreactor server service (if running locally)
# Windows: net stop PDFreactor
# Linux: sudo systemctl stop pdfreactor

# Install IronPDF
dotnet add package IronPdf
# Remove PDFreactor NuGet packages
dotnet remove package PDFreactor.NET
dotnet remove package PDFreactor.Native.Windows.x64

# Stop PDFreactor server service (if running locally)
# Windows: net stop PDFreactor
# Linux: sudo systemctl stop pdfreactor

# Install IronPDF
dotnet add package IronPdf
SHELL

License Configuration

PDFreactor (server-based):

// License configured on server via config file or command line
// Client connects to licensed server
var pdfReactor = new PDFreactor("http://pdfreactor-server:9423");
// License configured on server via config file or command line
// Client connects to licensed server
var pdfReactor = new PDFreactor("http://pdfreactor-server:9423");
$vbLabelText   $csharpLabel

IronPDF (application-level):

// One-time setup at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// One-time setup at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
$vbLabelText   $csharpLabel

Identify PDFreactor Usage

# Find PDFreactor usage
grep -r "PDFreactor\|RealObjects\|Configuration.*Document" --include="*.cs" .

# Find CSS Paged Media rules to convert
grep -r "@page\|counter(page)\|counter(pages)" --include="*.cs" --include="*.css" .
# Find PDFreactor usage
grep -r "PDFreactor\|RealObjects\|Configuration.*Document" --include="*.cs" .

# Find CSS Paged Media rules to convert
grep -r "@page\|counter(page)\|counter(pages)" --include="*.cs" --include="*.css" .
SHELL

Complete API Reference

Namespace Changes

// Before: PDFreactor
using RealObjects.PDFreactor;
using System.IO;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
// Before: PDFreactor
using RealObjects.PDFreactor;
using System.IO;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
$vbLabelText   $csharpLabel

Core Class Mappings

PDFreactorIronPDFNotes
PDFreactorChromePdfRendererMain conversion class
ConfigurationChromePdfRenderOptionsPDF settings
ResultPdfDocumentOutput document
config.Document = htmlrenderer.RenderHtmlAsPdf(html)HTML input
result.Document (byte[])pdf.BinaryDataRaw bytes

Configuration Property Mappings

PDFreactor ConfigurationIronPDF RenderingOptionsNotes
config.Document = htmlrenderer.RenderHtmlAsPdf(html)HTML content
config.Document = urlrenderer.RenderUrlAsPdf(url)URL conversion
config.PageFormat = PageFormat.A4RenderingOptions.PaperSize = PdfPaperSize.A4Paper size
config.PageOrientationRenderingOptions.PaperOrientationOrientation
config.PageMarginsRenderingOptions.MarginTop/Bottom/Left/RightMargins (mm)
config.EnableJavaScript = trueRenderingOptions.EnableJavaScript = trueJS execution
config.AddUserStyleSheet(css)Embed CSS in HTMLCSS injection
config.Titlepdf.MetaData.TitleMetadata
config.Encryptionpdf.SecuritySettingsSecurity

New Features Not Available in PDFreactor

IronPDF FeatureDescription
PdfDocument.Merge()Merge multiple PDFs
pdf.ApplyWatermark()Add watermarks
pdf.ExtractAllText()Text extraction
pdf.FormForm filling
pdf.Sign()Digital signatures

Code Migration Examples

Example 1: HTML String to PDF Conversion

Before (PDFreactor):

// NuGet: Install-Package PDFreactor.Native.Windows.x64
using RealObjects.PDFreactor;
using System.IO;

class Program
{
    static void Main()
    {
        PDFreactor pdfReactor = new PDFreactor();

        string html = "<html><body><h1>Hello World</h1></body></html>";

        Configuration config = new Configuration();
        config.Document = html;

        Result result = pdfReactor.Convert(config);

        File.WriteAllBytes("output.pdf", result.Document);
    }
}
// NuGet: Install-Package PDFreactor.Native.Windows.x64
using RealObjects.PDFreactor;
using System.IO;

class Program
{
    static void Main()
    {
        PDFreactor pdfReactor = new PDFreactor();

        string html = "<html><body><h1>Hello World</h1></body></html>";

        Configuration config = new Configuration();
        config.Document = html;

        Result result = pdfReactor.Convert(config);

        File.WriteAllBytes("output.pdf", result.Document);
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

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

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

        string html = "<html><body><h1>Hello World</h1></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

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

        string html = "<html><body><h1>Hello World</h1></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

The fundamental difference is the architectural pattern. PDFreactor requires creating a PDFreactor instance (which connects to the Java server), a separate Configuration object to hold settings and HTML content, calling Convert() which returns a Result object, and finally writing the result.Document bytes to file using File.WriteAllBytes().

IronPDF simplifies this to creating a ChromePdfRenderer, calling RenderHtmlAsPdf() directly with the HTML string, and using the built-in SaveAs() method on the returned PdfDocument. No server connection, no configuration object, no manual byte handling. See the HTML to PDF documentation for comprehensive examples.

Example 2: URL to PDF Conversion

Before (PDFreactor):

// NuGet: Install-Package PDFreactor.Native.Windows.x64
using RealObjects.PDFreactor;
using System.IO;

class Program
{
    static void Main()
    {
        PDFreactor pdfReactor = new PDFreactor();

        Configuration config = new Configuration();
        config.Document = "https://www.example.com";

        Result result = pdfReactor.Convert(config);

        File.WriteAllBytes("webpage.pdf", result.Document);
    }
}
// NuGet: Install-Package PDFreactor.Native.Windows.x64
using RealObjects.PDFreactor;
using System.IO;

class Program
{
    static void Main()
    {
        PDFreactor pdfReactor = new PDFreactor();

        Configuration config = new Configuration();
        config.Document = "https://www.example.com";

        Result result = pdfReactor.Convert(config);

        File.WriteAllBytes("webpage.pdf", result.Document);
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

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

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

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

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

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

PDFreactor uses the same config.Document property for both HTML strings and URLs, determining the type automatically. IronPDF provides explicit methods: RenderHtmlAsPdf() for HTML strings and RenderUrlAsPdf() for URLs. This explicit approach improves code clarity and IntelliSense support. Learn more in our tutorials.

Example 3: Headers and Footers with Page Numbers

Before (PDFreactor):

// NuGet: Install-Package PDFreactor.Native.Windows.x64
using RealObjects.PDFreactor;
using System.IO;

class Program
{
    static void Main()
    {
        PDFreactor pdfReactor = new PDFreactor();

        string html = "<html><body><h1>Document with Headers</h1><p>Content here</p></body></html>";

        Configuration config = new Configuration();
        config.Document = html;
        config.AddUserStyleSheet("@page { @top-center { content: 'Header Text'; } @bottom-center { content: 'Page ' counter(page); } }");

        Result result = pdfReactor.Convert(config);

        File.WriteAllBytes("document.pdf", result.Document);
    }
}
// NuGet: Install-Package PDFreactor.Native.Windows.x64
using RealObjects.PDFreactor;
using System.IO;

class Program
{
    static void Main()
    {
        PDFreactor pdfReactor = new PDFreactor();

        string html = "<html><body><h1>Document with Headers</h1><p>Content here</p></body></html>";

        Configuration config = new Configuration();
        config.Document = html;
        config.AddUserStyleSheet("@page { @top-center { content: 'Header Text'; } @bottom-center { content: 'Page ' counter(page); } }");

        Result result = pdfReactor.Convert(config);

        File.WriteAllBytes("document.pdf", result.Document);
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

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

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

        renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
        {
            CenterText = "Header Text"
        };

        renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
        {
            CenterText = "Page {page}"
        };

        string html = "<html><body><h1>Document with Headers</h1><p>Content here</p></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("document.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

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

        renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
        {
            CenterText = "Header Text"
        };

        renderer.RenderingOptions.TextFooter = new TextHeaderFooter()
        {
            CenterText = "Page {page}"
        };

        string html = "<html><body><h1>Document with Headers</h1><p>Content here</p></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("document.pdf");
    }
}
$vbLabelText   $csharpLabel

This example shows the most significant syntax difference. PDFreactor uses CSS Paged Media syntax with @page rules, @top-center/@bottom-center regions, and counter(page) for page numbers injected via AddUserStyleSheet().

IronPDF uses a native .NET API with TextHeaderFooter objects assigned to RenderingOptions.TextHeader and RenderingOptions.TextFooter. Page numbers use the {page} placeholder instead of CSS counter(page). Note that IronPDF also requires importing the IronPdf.Rendering namespace for header/footer classes.


Critical Migration Notes

No Server Required

IronPDF runs in-process—no Java server to configure:

// PDFreactor: Requires server connection
var pdfReactor = new PDFreactor("http://localhost:9423");

// IronPDF: No server URL needed
var renderer = new ChromePdfRenderer();
// PDFreactor: Requires server connection
var pdfReactor = new PDFreactor("http://localhost:9423");

// IronPDF: No server URL needed
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

CSS Paged Media to IronPDF API

Replace CSS @page rules with RenderingOptions:

// PDFreactor CSS: @page { @bottom-center { content: 'Page ' counter(page); } }
// IronPDF equivalent:
renderer.RenderingOptions.TextFooter = new TextHeaderFooter 
{ 
    CenterText = "Page {page}" 
};
// PDFreactor CSS: @page { @bottom-center { content: 'Page ' counter(page); } }
// IronPDF equivalent:
renderer.RenderingOptions.TextFooter = new TextHeaderFooter 
{ 
    CenterText = "Page {page}" 
};
$vbLabelText   $csharpLabel

Page Number Placeholder Syntax

// PDFreactor CSS: counter(page)
// IronPDF: {page}

// PDFreactor CSS: counter(pages)  
// IronPDF: {total-pages}
// PDFreactor CSS: counter(page)
// IronPDF: {page}

// PDFreactor CSS: counter(pages)  
// IronPDF: {total-pages}
$vbLabelText   $csharpLabel

Result Handling Change

Configuration + Result pattern becomes direct PdfDocument:

// PDFreactor: Configuration → Convert → Result → bytes
Result result = pdfReactor.Convert(config);
byte[] bytes = result.Document;
File.WriteAllBytes("output.pdf", bytes);

// IronPDF: Direct PdfDocument with built-in methods
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Or: byte[] bytes = pdf.BinaryData;
// PDFreactor: Configuration → Convert → Result → bytes
Result result = pdfReactor.Convert(config);
byte[] bytes = result.Document;
File.WriteAllBytes("output.pdf", bytes);

// IronPDF: Direct PdfDocument with built-in methods
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Or: byte[] bytes = pdf.BinaryData;
$vbLabelText   $csharpLabel

Margin Units Change

PDFreactor uses strings; IronPDF uses millimeters:

// PDFreactor: config.PageMargins.Top = "1in"
// IronPDF: renderer.RenderingOptions.MarginTop = 25.4  // 1 inch in mm
// PDFreactor: config.PageMargins.Top = "1in"
// IronPDF: renderer.RenderingOptions.MarginTop = 25.4  // 1 inch in mm
$vbLabelText   $csharpLabel

New Capabilities After Migration

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

PDF Merging

var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
$vbLabelText   $csharpLabel

Watermarks

pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>");
pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>");
$vbLabelText   $csharpLabel

Text Extraction

string text = pdf.ExtractAllText();
string text = pdf.ExtractAllText();
$vbLabelText   $csharpLabel

Password Protection

pdf.SecuritySettings.UserPassword = "userpassword";
pdf.SecuritySettings.OwnerPassword = "ownerpassword";
pdf.SecuritySettings.UserPassword = "userpassword";
pdf.SecuritySettings.OwnerPassword = "ownerpassword";
$vbLabelText   $csharpLabel

Feature Comparison Summary

FeaturePDFreactorIronPDF
HTML to PDF
URL to PDF
Headers/FootersCSS Paged MediaNative API
Page Settings
JavaScript Support
Native .NET
In-Process
Merge PDFs
Split PDFs
Watermarks
Text Extraction
Form Filling
Digital Signatures

Migration Checklist

Pre-Migration

  • Inventory all PDFreactor usage in codebase
  • Document all CSS Paged Media rules used
  • Note all configuration settings (margins, page size, JavaScript)
  • Plan IronPDF license key storage (environment variables recommended)
  • Test with IronPDF trial license first

Package Changes

  • Remove PDFreactor.NET NuGet package
  • Remove PDFreactor.Native.Windows.x64 NuGet package
  • Install IronPdf NuGet package: dotnet add package IronPdf

Code Changes

  • Update namespace imports (using RealObjects.PDFreactor;using IronPdf;)
  • Add using IronPdf.Rendering; for header/footer classes
  • Replace PDFreactor class with ChromePdfRenderer
  • Convert Configuration objects to RenderingOptions properties
  • Replace config.Document = html with renderer.RenderHtmlAsPdf(html)
  • Replace config.Document = url with renderer.RenderUrlAsPdf(url)
  • Replace File.WriteAllBytes(path, result.Document) with pdf.SaveAs(path)
  • Convert CSS @page rules to TextHeader/TextFooter objects
  • Update page number placeholders (counter(page){page})
  • Convert margin units from strings to millimeters

Infrastructure Migration

  • Remove Java runtime requirement
  • Decommission PDFreactor server
  • Update Docker/deployment configurations
  • Update CI/CD pipelines

Post-Migration

  • Test PDF output quality matches expectations
  • Verify header/footer rendering
  • Verify JavaScript execution if used
  • Add new capabilities (merging, watermarks, security) as needed

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