IRONSOFTWAREHOME
MIGRATION GUIDES

Migrate from ActivePDF to IronPDF: (.NET Guide)

Curtis Chau
Curtis Chau
Updated: July 19, 2026

ActivePDF has been a dependable PDF toolkit for .NET developers. Since PDFTron acquired it in June 2020 and rebranded to Apryse in February 2023, ActivePDF now sits as one of several brands inside the broader Apryse portfolio. This guide offers a thorough, step-by-step migration path from ActivePDF to IronPDF - a modern, actively maintained .NET PDF library supporting .NET Framework 4.6.2 through .NET 9.

Why Consider Moving Away from ActivePDF?

ActivePDF still ships and the ActivePDF.Toolkit NuGet package continues to receive updates under Apryse, but several aspects of its design and packaging can prompt teams to evaluate alternatives.

Brand and Roadmap Considerations

ActivePDF is now one brand inside Apryse, alongside the flagship Apryse SDK. Teams that picked ActivePDF specifically for its server-side automation focus may want to weigh whether to stay on the ActivePDF SKUs or move to the broader Apryse SDK over time.

Licensing Model

ActivePDF's traditional per-server/per-core licensing can introduce friction in cloud and containerized environments where applications scale dynamically across infrastructure.

Legacy Architecture Patterns

ActivePDF's API surface reflects its COM/native origins. The OpenOutputFile/CloseOutputFile workflow and integer return codes (0 for success) require explicit lifecycle management that doesn't always align with modern C# idioms like using, exceptions, and async.

Multi-SKU Product Layout

HTML/URL-to-PDF rendering lives in the separate ActivePDF.WebGrabber product, while PDF manipulation lives in ActivePDF.Toolkit. Starting with Toolkit 10, the native libraries are no longer auto-copied to the system folder, so the constructor often needs an explicit CoreLibPath argument - a pattern that can complicate Docker, CI, and installer-less deployments.

ActivePDF vs. IronPDF: Key Differences

Before starting the migration process, understanding the fundamental differences between ActivePDF and IronPDF helps set expectations for the code changes required.

AspectActivePDFIronPDF
VendorApryse (formerly PDFTron, acquired ActivePDF June 2020)Iron Software, independent
Product LayoutMultiple SKUs (Toolkit, WebGrabber, DocConverter, Server, Meridian)Single IronPdf NuGet package
InstallationNuGet package + native runtime path (CoreLibPath since v10)Single NuGet package; natives bundled
API PatternStateful (OpenOutputFile/CloseOutputFile), COM-derivedFluent, functional API
License ModelPer-server / per-coreCode-based key
.NET Support.NET Framework 4.5+ / .NET Standard 1.0+ / .NET CoreFramework 4.6.2 to .NET 9
Error HandlingInteger return codes (0 = success)Standard .NET exceptions
Async SupportNot nativeFull async/await support

Pre-Migration Preparation

Audit Your Codebase

Before beginning migration, identify all ActivePDF usage across your solution. The real namespaces are APToolkitNET (Toolkit) and APWebGrabber (WebGrabber); a few legacy projects also reference ActivePDF.Toolkit via the COM interop assembly. Run these commands in your solution directory:

grep -r "using APToolkitNET" --include="*.cs" .
grep -r "using APWebGrabber" --include="*.cs" .
grep -r "ActivePDF" --include="*.csproj" .
SHELL

Document Breaking Changes

Understanding the fundamental API differences helps plan your migration strategy:

CategoryActivePDF BehaviorIronPDF BehaviorMigration Action
Product SplitToolkit (manipulation) + WebGrabber (HTML rendering) sold separatelySingle IronPdf packageCollapse both into one library
Object ModelAPToolkitNET.Toolkit for PDFs, APWebGrabber.WebGrabber for HTMLChromePdfRenderer + PdfDocumentSeparate concerns
File OperationsOpenOutputFile()/CloseOutputFile()Direct SaveAs()Remove open/close calls
Native RuntimeCoreLibPath argument since v10NuGet ships nativesRemove path configuration
Page CreationNewPage() methodAutomatic from HTMLRemove page creation calls
Return ValuesInteger error codesExceptionsImplement try/catch
Page Size UnitsPoints (612x792 = Letter)Enums or millimetersUpdate measurements

Prerequisites

Ensure your environment meets these requirements:

  • .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
  • Visual Studio 2019+ or JetBrains Rider
  • NuGet Package Manager access
  • IronPDF license key (free trial available at ironpdf.com)

Step-by-Step Migration Process

Step 1: Update NuGet Packages

The package on nuget.org is ActivePDF.Toolkit (current version 11.4.4, published December 2025). HTML rendering ships separately as ActivePDF.WebGrabber. Remove the ActivePDF SKUs and install IronPDF:

# Remove ActivePDF packages
dotnet remove package ActivePDF.Toolkit
dotnet remove package ActivePDF.WebGrabber

# Install IronPDF
dotnet add package IronPdf
SHELL

Alternatively, via the Visual Studio Package Manager Console:

Uninstall-Package ActivePDF.Toolkit
Uninstall-Package ActivePDF.WebGrabber
Install-Package IronPdf
PowerShell

For projects with manual DLL references, remove the reference from your .csproj file:

<!-- Remove this block -->
<Reference Include="APToolkitNET">
    <HintPath>path\to\APToolkitNET.dll</HintPath>
</Reference>
XML

Step 2: Configure the License Key

Add the IronPDF license key at application startup, before any PDF operations:

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;

Step 3: Update Namespace References

Perform a global find-and-replace across your solution:

FindReplace With
using APToolkitNET;using IronPdf;
using APWebGrabber;using IronPdf;
APToolkitNET.ToolkitChromePdfRenderer (rendering) / PdfDocument (manipulation)
APWebGrabber.WebGrabberChromePdfRenderer

Complete API Migration Reference

Document Creation Methods

ActivePDF MethodIronPDF EquivalentNotes
new APToolkitNET.Toolkit()new ChromePdfRenderer() / new PdfDocument(...)IronPDF separates rendering from manipulation
new Toolkit(CoreLibPath: path)new ChromePdfRenderer()NuGet ships natives - no CoreLibPath
toolkit.OpenOutputFile(path)No equivalent neededJust call SaveAs at end
toolkit.CloseOutputFile()No equivalent neededusing handles cleanup
webGrabber.URL = html; webGrabber.ConvertToPDF()renderer.RenderHtmlAsPdf(html)WebGrabber, not Toolkit
webGrabber.URL = url; webGrabber.ConvertToPDF()renderer.RenderUrlAsPdf(url)WebGrabber, not Toolkit

File Operations

ActivePDF MethodIronPDF EquivalentNotes
toolkit.OpenInputFile(path)PdfDocument.FromFile(path)Load existing PDF
toolkit.MergeFile(path, startPage, endPage)PdfDocument.Merge(pdfs)ActivePDF merges into the open output file in-place; IronPDF returns a new merged document
toolkit.NumPages (property)pdf.PageCountPage count
toolkit.GetPageText(page, 0)pdf.Pages[i].Text / pdf.ExtractAllText()Text extraction

Page Configuration

ActivePDF MethodIronPDF Equivalent
toolkit.SetPageSize(612, 792)RenderingOptions.PaperSize = PdfPaperSize.Letter
toolkit.SetOrientation("Landscape")RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
toolkit.SetMargins(t, b, l, r)RenderingOptions.MarginTop/Bottom/Left/Right

Security Methods

ActivePDF MethodIronPDF Equivalent
toolkit.SetEncryption(user, owner, 128, 0)pdf.SecuritySettings.OwnerPassword / UserPassword
toolkit.SetPermissions(flags)pdf.SecuritySettings.AllowUserXxx
toolkit.PrintText(x, y, text) (per-page watermark)pdf.ApplyWatermark(html)

Code Migration Examples

HTML to PDF Conversion

Converting HTML strings to PDF documents represents one of the most common PDF generation scenarios. Note that in ActivePDF, HTML rendering lives in the separately-licensed WebGrabber product, not Toolkit, and WebGrabber renders from a URL or file path rather than an in-memory string.

ActivePDF Implementation (WebGrabber):

// NuGet: Install-Package ActivePDF.WebGrabber
using APWebGrabber;
using System;
using System.IO;

class Program
{
    static void Main()
    {
        WebGrabber wg = new WebGrabber();

        string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
        string tempHtml = Path.Combine(Path.GetTempPath(), "input.html");
        File.WriteAllText(tempHtml, htmlContent);

        wg.URL = tempHtml;
        wg.OutputDirectory = Directory.GetCurrentDirectory();
        wg.OutputFilename = "output.pdf";

        if (wg.ConvertToPDF() == 0)
        {
            Console.WriteLine("PDF created successfully");
        }
    }
}

IronPDF Implementation:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        
        string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
        
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("output.pdf");
        
        Console.WriteLine("PDF created successfully");
    }
}

The IronPDF approach eliminates the explicit file handle management while providing cleaner, more readable code. For advanced HTML to PDF scenarios, IronPDF's ChromePdfRenderer uses a Chromium-based rendering engine for pixel-perfect CSS and JavaScript support.

URL to PDF Conversion

Capturing web pages as PDF documents also lives in WebGrabber, not Toolkit.

ActivePDF Implementation (WebGrabber):

// NuGet: Install-Package ActivePDF.WebGrabber
using APWebGrabber;
using System;
using System.IO;

class Program
{
    static void Main()
    {
        WebGrabber wg = new WebGrabber();

        wg.URL = "https://www.example.com";
        wg.OutputDirectory = Directory.GetCurrentDirectory();
        wg.OutputFilename = "webpage.pdf";

        if (wg.ConvertToPDF() == 0)
        {
            Console.WriteLine("PDF from URL created successfully");
        }
    }
}

IronPDF Implementation:

using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        
        string url = "https://www.example.com";
        
        var pdf = renderer.RenderUrlAsPdf(url);
        pdf.SaveAs("webpage.pdf");
        
        Console.WriteLine("PDF from URL created successfully");
    }
}

Merging Multiple PDFs

Combining multiple PDF documents into a single file demonstrates IronPDF's functional approach to document manipulation.

ActivePDF Implementation (Toolkit):

// NuGet: Install-Package ActivePDF.Toolkit
using APToolkitNET;
using System;

class Program
{
    static void Main()
    {
        using (Toolkit toolkit = new Toolkit())
        {
            if (toolkit.OpenOutputFile("merged.pdf") == 0)
            {
                // MergeFile(FileName, StartPage, EndPage); -1 = end of file
                toolkit.MergeFile("document1.pdf", 1, -1);
                toolkit.MergeFile("document2.pdf", 1, -1);
                toolkit.CloseOutputFile();
                Console.WriteLine("PDFs merged successfully");
            }
        }
    }
}

IronPDF Implementation:

using IronPdf;
using System;
using System.Collections.Generic;

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");
        
        Console.WriteLine("PDFs merged successfully");
    }
}

For more advanced merging scenarios including selective page extraction, see the PDF merging documentation.

Adding Headers and Footers

ActivePDF Implementation (WebGrabber):

using APWebGrabber;
using System.IO;

public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
    var wg = new WebGrabber();
    string tempHtml = Path.Combine(Path.GetTempPath(), "input.html");
    File.WriteAllText(tempHtml, html);

    wg.URL = tempHtml;
    wg.HeaderText = "My Document";
    wg.FooterText = "Page [page] of [pages]";
    wg.OutputDirectory = Path.GetDirectoryName(outputPath);
    wg.OutputFilename = Path.GetFileName(outputPath);
    wg.ConvertToPDF();
}

IronPDF Implementation:

using IronPdf;

public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
    var renderer = new ChromePdfRenderer();

    renderer.RenderingOptions.TextHeader = new TextHeaderFooter
    {
        CenterText = "My Document",
        FontSize = 12,
        FontFamily = "Arial"
    };

    renderer.RenderingOptions.TextFooter = new TextHeaderFooter
    {
        CenterText = "Page {page} of {total-pages}",
        FontSize = 10,
        FontFamily = "Arial"
    };

    using var pdf = renderer.RenderHtmlAsPdf(html);
    pdf.SaveAs(outputPath);
}

IronPDF supports both text-based and HTML headers and footers, providing complete design flexibility.

Password Protection and Security

ActivePDF Implementation (Toolkit):

using APToolkitNET;

public void ProtectPdf(string inputPath, string outputPath, string password)
{
    using (Toolkit toolkit = new Toolkit())
    {
        if (toolkit.OpenOutputFile(outputPath) == 0
            && toolkit.OpenInputFile(inputPath) == 0)
        {
            toolkit.SetEncryption(password, password, 128, 0);
            toolkit.CopyForm(0, 0);
            toolkit.CloseInputFile();
            toolkit.CloseOutputFile();
        }
    }
}

IronPDF Implementation:

using IronPdf;

public void ProtectPdf(string inputPath, string outputPath, string password)
{
    using var pdf = PdfDocument.FromFile(inputPath);

    pdf.SecuritySettings.OwnerPassword = password;
    pdf.SecuritySettings.UserPassword = password;
    pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
    pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;

    pdf.SaveAs(outputPath);
}

IronPDF's security settings API provides granular control over document permissions with strongly-typed enums instead of integer flags.

Text Extraction

ActivePDF Implementation (Toolkit):

using APToolkitNET;
using System.Text;

public string ExtractText(string pdfPath)
{
    var sb = new StringBuilder();

    using (Toolkit toolkit = new Toolkit())
    {
        if (toolkit.OpenInputFile(pdfPath) == 0)
        {
            int pageCount = toolkit.NumPages;
            for (int i = 1; i <= pageCount; i++)
            {
                sb.AppendLine(toolkit.GetPageText(i, 0));
            }
            toolkit.CloseInputFile();
        }
    }

    return sb.ToString();
}

IronPDF Implementation:

using IronPdf;

public string ExtractText(string pdfPath)
{
    using var pdf = PdfDocument.FromFile(pdfPath);
    return pdf.ExtractAllText();
}

The IronPDF implementation reduces text extraction from multiple lines to a single method call.

Adding Watermarks

ActivePDF Implementation (Toolkit - drawn as page text per page):

using APToolkitNET;

public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
    using (Toolkit toolkit = new Toolkit())
    {
        if (toolkit.OpenOutputFile(outputPath) == 0
            && toolkit.OpenInputFile(inputPath) == 0)
        {
            int pageCount = toolkit.NumPages;
            for (int i = 1; i <= pageCount; i++)
            {
                toolkit.CopyForm(i, 0);
                toolkit.SetFont("Helvetica", 72);
                toolkit.SetTextColor(200, 200, 200);
                toolkit.PrintText(150, 400, watermarkText);
            }
            toolkit.CloseInputFile();
            toolkit.CloseOutputFile();
        }
    }
}

IronPDF Implementation:

using IronPdf;

public void AddWatermark(string inputPath, string outputPath, string watermarkText)
{
    using var pdf = PdfDocument.FromFile(inputPath);

    pdf.ApplyWatermark(
        $"<h1 style='color:lightgray;font-size:72px;'>{watermarkText}</h1>",
        rotation: 45,
        opacity: 50);

    pdf.SaveAs(outputPath);
}

IronPDF's HTML-based watermarking enables CSS styling for complete design control without page-by-page iteration.

ASP.NET Core Integration

Modern web applications benefit significantly from IronPDF's cleaner integration patterns.

ActivePDF Pattern (WebGrabber):

[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
    var wg = new APWebGrabber.WebGrabber();
    string tempHtml = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".html");
    System.IO.File.WriteAllText(tempHtml, request.Html);

    wg.URL = tempHtml;
    wg.OutputDirectory = Path.GetTempPath();
    wg.OutputFilename = "temp.pdf";

    if (wg.ConvertToPDF() == 0)
    {
        byte[] bytes = System.IO.File.ReadAllBytes(Path.Combine(Path.GetTempPath(), "temp.pdf"));
        return File(bytes, "application/pdf", "report.pdf");
    }

    return BadRequest("PDF generation failed");
}

IronPDF Pattern:

[HttpPost]
public IActionResult GeneratePdf([FromBody] ReportRequest request)
{
    var renderer = new ChromePdfRenderer();
    using var pdf = renderer.RenderHtmlAsPdf(request.Html);

    return File(pdf.BinaryData, "application/pdf", "report.pdf");
}

IronPDF eliminates the need for temporary files, returning the PDF binary data directly from memory.

Async Support for Web Applications

ActivePDF lacks native async support. IronPDF provides full async/await capabilities essential for scalable web applications:

using IronPdf;

public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}

Dependency Injection Configuration

For .NET 6+ applications, register IronPDF services in your DI container:

// Program.cs (.NET 6+)
builder.Services.AddSingleton<ChromePdfRenderer>();

// Service wrapper
public interface IPdfService
{
    Task<byte[]> GeneratePdfAsync(string html);
    Task<byte[]> GeneratePdfFromUrlAsync(string url);
}

public class IronPdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;

    public IronPdfService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
    }

    public async Task<byte[]> GeneratePdfAsync(string html)
    {
        using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
        return pdf.BinaryData;
    }

    public async Task<byte[]> GeneratePdfFromUrlAsync(string url)
    {
        using var pdf = await _renderer.RenderUrlAsPdfAsync(url);
        return pdf.BinaryData;
    }
}

Error Handling Migration

ActivePDF uses integer return codes requiring lookup tables. IronPDF uses modern exception handling:

ActivePDF Error Handling:

using APToolkitNET;

using (var toolkit = new Toolkit())
{
    int result = toolkit.OpenOutputFile(path);

    if (result != 0)
    {
        // Error - look up the code in "Toolkit Return Results and Error Codes"
        Console.WriteLine($"Error code: {result}");
    }
}

IronPDF Error Handling:

try
{
    var renderer = new ChromePdfRenderer();
    using var pdf = renderer.RenderHtmlAsPdf(html);
    pdf.SaveAs(path);
}
catch (IronPdf.Exceptions.IronPdfProductException ex)
{
    Console.WriteLine($"IronPDF Error: {ex.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"General Error: {ex.Message}");
}

Performance Optimization Tips

Reuse the Renderer Instance

Creating a new ChromePdfRenderer has initialization overhead. For batch operations, reuse a single instance:

var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
    using var pdf = renderer.RenderHtmlAsPdf(html);
    pdf.SaveAs($"output_{i}.pdf");
}

Use Async in Web Applications

For ASP.NET Core applications, async PDF generation improves throughput:

public async Task<IActionResult> GenerateReport()
{
    var renderer = new ChromePdfRenderer();
    using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return File(pdf.BinaryData, "application/pdf");
}

Proper Resource Disposal

Always use using statements to ensure proper cleanup:

using var pdf = renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;

Image Compression

Reduce output file sizes with image compression:

using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.CompressImages(85); // 85% quality
pdf.SaveAs("compressed.pdf");

Troubleshooting Common Migration Issues

Issue: Page Size Differences

ActivePDF WebGrabber uses points (612x792 = Letter), while IronPDF uses enums or millimeters:

// ActivePDF WebGrabber: Points
wg.PageWidth = 612;
wg.PageHeight = 792;

// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom in mm:
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(215.9, 279.4);

Issue: Missing CloseOutputFile Equivalent

IronPDF uses a modern paradigm without explicit file handle management:

// ActivePDF Toolkit
toolkit.OpenOutputFile(path);
// ... operations ...
toolkit.CloseOutputFile(); // Required!

// IronPDF - no open/close needed
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(path); // 'using' handles cleanup

Issue: PDF Renders Blank

If JavaScript-dependent content renders blank, configure render delays:

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.RenderDelay(2000);
// Or wait for element:
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");

Issue: CSS/Images Not Loading

Configure the base URL for relative path resolution:

renderer.RenderingOptions.BaseUrl = new Uri("https://yourdomain.com/assets/");

Post-Migration Checklist

After completing the code migration, verify the following:

  • Run all existing unit and integration tests
  • Compare PDF outputs visually against previous versions
  • Test all PDF workflows in a staging environment
  • Verify licensing works correctly (IronPdf.License.IsLicensed)
  • Benchmark performance against previous implementation
  • Remove old ActivePDF installation files and DLL references
  • Update CI/CD pipeline dependencies
  • Document IronPDF patterns for your development team

Additional Resources


Migrating from ActivePDF to IronPDF modernizes your PDF generation infrastructure with cleaner APIs, better .NET integration, and active long-term support. The investment in migration pays dividends through improved code maintainability, async capabilities, and confidence in your PDF library's continued development.

Please note: ActivePDF and Apryse are registered trademarks of their respective owners. This site is not affiliated with, endorsed by, or sponsored by ActivePDF or Apryse. All product names, logos, and brands are property of their respective owners. Comparisons are for informational purposes only and reflect publicly available information at the time of writing.
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

Related Articles

Key in blue circle

Get your free 30-day Trial Key instantly.

Your trial license will be sent to your email address

No limitations. 100% unlocked. No credit card.

bullet_checkedNo credit card or account creation requiredNo limitations. 100% unlocked. No credit card.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Book your free Live Demo
Booking Badge

Trusted by Millions of Engineers Worldwide

Iron Software's customer logos
Get Your No-Obligation Consult
Complete the form below or email sales@ironsoftware.com
Your details will always be kept confidential.
Trusted by Millions of Engineers Worldwide
Iron Software's customer logos
Get your free 30-day Trial Key instantly.
No credit card or account creation required