IRONSOFTWAREHOME
MIGRATION GUIDES

How to Migrate from WebView2 to IronPDF in C#

Curtis Chau
Curtis Chau
Updated: August 1, 2026

WebView2, Microsoft's embeddable Edge/Chromium browser control (Microsoft.Web.WebView2), offers developers a way to display web content within Windows applications. However, when development teams attempt to use WebView2 for PDF generation, they encounter architectural limitations that make it a poor fit for headless and server scenarios. WebView2 is a browser embedding control designed for UI applications, not a PDF generation library.

This guide provides a migration path from WebView2 to IronPDF, with code comparisons and practical examples for .NET developers who need reliable PDF generation in their applications.

Why WebView2 Is a Poor Fit for PDF Generation

Before examining the migration path, it helps to understand why WebView2 is a poor fit for headless PDF creation:

ProblemImpactSeverity
Memory LeaksMemory growth reported in long-running processes that repeatedly create WebView2 instances.HIGH
Windows-OnlyNo support for Linux, macOS, Docker, or non-Windows cloud environmentsCRITICAL
UI Thread RequiredMust run on an STA thread with a message pump. Not suitable for web servers or background APIs.CRITICAL
Not Designed for PDFsPrintToPdfAsync is a secondary capability, not a core featureHIGH
Unstable in ServicesCrashes and hangs reported in Windows Services and background workersHIGH
Complex Async FlowNavigation events, completion callbacks, race conditionsHIGH
Edge Runtime DependencyRequires the Edge WebView2 Runtime installed on the target machineMEDIUM
No Headless ModeDesigned around a UI control; not a headless rendererMEDIUM
PerformanceSlow startup, heavy resource consumptionMEDIUM
No PDF Support StoryMicrosoft doesn't position WebView2 as a PDF generation productMEDIUM

Real-World Failure Scenarios

These code patterns commonly cause issues in production:

// WARNING: These patterns are known to cause problems in headless / server scenarios

// Problem 1: Memory growth - creates a new WebView2 per PDF
public async Task<byte[]> GeneratePdf(string html) // High call volume accumulates memory
{
    using var webView = new WebView2(); // Disposal does not fully reclaim native resources
    await webView.EnsureCoreWebView2Async();
    webView.CoreWebView2.NavigateToString(html);
    // ... memory growth reported over time
}

// Problem 2: UI thread requirement - crashes in ASP.NET
public IActionResult GenerateReport() // FAILS - no STA thread
{
    var webView = new WebView2(); // InvalidOperationException
}

// Problem 3: Windows Service instability
public class PdfService : BackgroundService // Random crashes
{
    protected override async Task ExecuteAsync(CancellationToken token)
    {
        // WebView2 + no message pump = hangs, crashes, undefined behavior
    }
}

IronPDF vs WebView2: Feature Comparison

Understanding the architectural differences helps technical decision-makers evaluate the migration investment:

AspectWebView2IronPDF
PurposeBrowser control (UI)PDF library (designed for PDF)
Production ReadyNOYES
Memory ManagementMemory growth reported in long-runningStable, properly disposed
Platform SupportWindows onlyWindows, Linux, macOS, Docker
Thread RequirementsSTA + Message PumpAny thread
Server/CloudNot supportedSupported
Azure/AWS/GCPProblematicWorks perfectly
DockerNot possibleOfficial images available
ASP.NET CoreCannot workFirst-class support
Background ServicesUnstableStable
Supported ContextsWinForms/WPF onlyAny .NET context: console, web, desktop
HTML to PDFBasicFull
URL to PDFBasicFull
Headers/FootersNOYes (HTML)
WatermarksNOYes
Merge PDFsNOYes
Split PDFsNOYes
Digital SignaturesNOYes
Password ProtectionNOYes
PDF/A ComplianceNOYes
Professional SupportNone for PDFYes
DocumentationLimitedExtensive

Quick Start: WebView2 to IronPDF Migration

The migration can begin immediately with these foundational steps.

Step 1: Remove WebView2 Package

dotnet remove package Microsoft.Web.WebView2
SHELL

Or remove from your project file:

<!-- REMOVE these packages -->
<PackageReference Include="Microsoft.Web.WebView2" Version="*" Remove />
XML

Step 2: Install IronPDF

dotnet add package IronPdf

Step 3: Update Namespaces

Replace WebView2 namespaces with the IronPDF namespace:

// Before (WebView2)
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;

// After (IronPDF)
using IronPdf;

Step 4: Initialize License

Add license initialization at application startup:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

Code Migration Examples

Converting HTML to PDF

The most fundamental operation reveals the complexity difference between these .NET PDF approaches.

WebView2 Approach:

// NuGet: Install-Package Microsoft.Web.WebView2
// (the WinForms host lives in the same package; no separate .WinForms package)
// Requires the Edge WebView2 Runtime installed on the target machine. Windows-only.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;

class Program
{
    static async Task Main()
    {
        var webView = new WebView2();
        await webView.EnsureCoreWebView2Async();

        webView.CoreWebView2.NavigateToString("<html><body><h1>Hello World</h1></body></html>");
        await Task.Delay(2000);

        // PrintToPdfAsync(path, settings) returns Task<bool>; null = default settings
        bool ok = await webView.CoreWebView2.PrintToPdfAsync("output.pdf", null);
    }
}

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;

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

The WebView2 version requires asynchronous initialization with EnsureCoreWebView2Async(), navigation via NavigateToString(), a Task.Delay(2000) to wait for rendering, and a final PrintToPdfAsync call that returns a Task<bool> indicating success. IronPDF eliminates this ceremony - create a renderer, render HTML, save.

For advanced HTML-to-PDF scenarios, see the HTML to PDF conversion guide.

Converting URLs to PDF

URL-to-PDF conversion demonstrates WebView2's complex async navigation flow.

WebView2 Approach:

// NuGet: Install-Package Microsoft.Web.WebView2
// (Edge Chromium control; requires Edge WebView2 Runtime; Windows-only.)
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;

class Program
{
    static async Task Main()
    {
        var webView = new WebView2();
        await webView.EnsureCoreWebView2Async();

        var tcs = new TaskCompletionSource<bool>();
        webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);

        webView.CoreWebView2.Navigate("https://example.com");
        await tcs.Task;
        await Task.Delay(1000);

        var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
            "Page.printToPDF",
            "{\"printBackground\": true}"
        );

        var base64 = System.Text.Json.JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
        File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
    }
}

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("output.pdf");
    }
}

WebView2 requires creating a TaskCompletionSource, subscribing to NavigationCompleted events, calling CallDevToolsProtocolMethodAsync, parsing JSON responses, and decoding base64 data. IronPDF provides a dedicated RenderUrlAsPdf method that handles all complexity internally.

Explore the URL to PDF documentation for authentication and custom header options.

Custom PDF Settings from HTML Files

Configuring page orientation, margins, and paper size requires different approaches.

WebView2 Approach:

// NuGet: Install-Package Microsoft.Web.WebView2
// CreatePrintSettings() lives on CoreWebView2Environment.
// Margin* / PageWidth / PageHeight on CoreWebView2PrintSettings are in INCHES.
// PrintToPdfAsync(path, settings) returns Task<bool> (true on success) — not a stream.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;

class Program
{
    static async Task Main()
    {
        var webView = new WebView2();
        await webView.EnsureCoreWebView2Async();

        string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
        webView.CoreWebView2.Navigate(htmlFile);

        await Task.Delay(3000);

        CoreWebView2PrintSettings printSettings = webView.CoreWebView2.Environment.CreatePrintSettings();
        printSettings.Orientation = CoreWebView2PrintOrientation.Landscape;
        printSettings.MarginTop = 0.5;     // inches
        printSettings.MarginBottom = 0.5;  // inches
        printSettings.ShouldPrintBackgrounds = true;

        bool ok = await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings);
        Console.WriteLine(ok ? "Custom PDF created" : "PrintToPdfAsync returned false");
    }
}

IronPDF Approach:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 50;
        renderer.RenderingOptions.MarginBottom = 50;
        
        string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
        var pdf = renderer.RenderHtmlFileAsPdf(htmlFile);
        pdf.SaveAs("custom.pdf");
        
        Console.WriteLine("Custom PDF created");
    }
}

WebView2 requires a 3-second Task.Delay (an unreliable guess), creating print settings through the CoreWebView2.Environment, and an await on PrintToPdfAsync(path, settings) that returns Task<bool> rather than a stream. WebView2 expresses margins in inches; IronPDF uses millimeters via direct RenderingOptions properties.

Advanced PDF Options with DevTools Protocol

Complex WebView2 configurations require DevTools Protocol interaction.

WebView2 Approach:

// NuGet: Install-Package Microsoft.Web.WebView2
// Uses raw Chrome DevTools Protocol via CallDevToolsProtocolMethodAsync.
// (Page.printToPDF returns base64 in result.data; units are inches.)
using System;
using System.IO;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;

class Program
{
    static async Task Main()
    {
        var webView = new WebView2();
        await webView.EnsureCoreWebView2Async();
        
        var htmlPath = Path.GetFullPath("document.html");
        var tcs = new TaskCompletionSource<bool>();
        webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
        
        webView.CoreWebView2.Navigate($"file:///{htmlPath}");
        await tcs.Task;
        await Task.Delay(1000);
        
        var options = new
        {
            landscape = false,
            printBackground = true,
            paperWidth = 8.5,
            paperHeight = 11,
            marginTop = 0.4,
            marginBottom = 0.4,
            marginLeft = 0.4,
            marginRight = 0.4
        };
        
        var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
            "Page.printToPDF",
            JsonSerializer.Serialize(options)
        );
        
        var base64 = JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
        File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
    }
}
C#

IronPDF Approach:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 40;
        renderer.RenderingOptions.MarginBottom = 40;
        renderer.RenderingOptions.MarginLeft = 40;
        renderer.RenderingOptions.MarginRight = 40;
        renderer.RenderingOptions.PrintHtmlBackgrounds = true;
        
        var pdf = renderer.RenderHtmlFileAsPdf("document.html");
        pdf.SaveAs("output.pdf");
    }
}

WebView2 requires constructing anonymous objects, serializing to JSON, calling DevTools Protocol methods, parsing JSON responses, and manually decoding base64. IronPDF provides typed properties with clear names and enum values like PdfPaperSize.Letter.

WebView2 API to IronPDF Mapping Reference

This mapping accelerates migration by showing direct API equivalents:

WebView2 APIIronPDF Equivalent
new WebView2()new ChromePdfRenderer()
EnsureCoreWebView2Async()N/A
NavigateToString(html) + PrintToPdfAsync()RenderHtmlAsPdf(html)
Navigate(url) + PrintToPdfAsync()RenderUrlAsPdf(url)
PrintSettings.PageWidthRenderingOptions.PaperSize
PrintSettings.PageHeightRenderingOptions.PaperSize
PrintSettings.MarginTopRenderingOptions.MarginTop
PrintSettings.OrientationRenderingOptions.PaperOrientation
ExecuteScriptAsync()JavaScript in HTML

| AddScriptToExecuteOnDocumentCreatedAsync() | HTML <script> tags | | Navigation events | WaitFor.JavaScript() | | CallDevToolsProtocolMethodAsync("Page.printToPDF") | RenderHtmlAsPdf() |

Common Migration Issues and Solutions

Issue 1: Memory Growth

WebView2 Problem: Memory growth is reported in long-running processes that repeatedly create WebView2 instances, particularly without a steady message pump.

IronPDF Solution: Predictable disposal and using-friendly lifecycle:

// IronPDF - clean memory management
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
    pdf.SaveAs("output.pdf");
} // Properly disposed

Issue 2: No UI Thread in Web Apps

WebView2 Problem: Requires STA thread with message pump. ASP.NET Core controllers cannot create WebView2 instances.

IronPDF Solution: Works on any thread:

// ASP.NET Core - just works
public async Task<IActionResult> GetPdf()
{
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return File(pdf.BinaryData, "application/pdf");
}

Issue 3: Navigation Event Complexity

WebView2 Problem: Must handle async navigation events, completion callbacks, and race conditions with TaskCompletionSource.

IronPDF Solution: Synchronous or async single method call:

// Simple and predictable
var pdf = renderer.RenderHtmlAsPdf(html);
// or
var pdf = await renderer.RenderHtmlAsPdfAsync(html);

Issue 4: Measurement Units

WebView2 uses inches for dimensions (8.5 x 11 for Letter). IronPDF uses millimeters for more precise measurements.

Conversion approach:

// WebView2: PageWidth = 8.27 (inches for A4)
// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

// Or custom size in mm
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(210, 297);

WebView2 Migration Checklist

Pre-Migration Tasks

Document all WebView2 PDF generation code in your codebase. Identify where WebView2 is causing problems (memory leaks, crashes, deployment issues). Review the IronPDF documentation to familiarize with capabilities.

Code Update Tasks

  1. Remove Microsoft.Web.WebView2 NuGet package
  2. Install IronPDF NuGet package
  3. Remove WinForms/WPF dependencies if only used for PDF generation
  4. Replace WebView2 code with ChromePdfRenderer
  5. Remove STA thread requirements
  6. Remove navigation event handlers and TaskCompletionSource patterns
  7. Remove Task.Delay hacks
  8. Add IronPDF license initialization at startup

Post-Migration Testing

After migration, verify these aspects:

  • Test in target environment (ASP.NET, Docker, Linux if applicable)
  • Verify PDF output quality matches expectations
  • Test JavaScript-heavy pages render correctly
  • Verify headers and footers work with IronPDF's HTML capabilities
  • Load test for memory stability over extended operations
  • Test long-running scenarios without memory accumulation

Deployment Updates

  • Update Docker images if applicable (remove Edge WebView2 Runtime)
  • Remove Edge WebView2 Runtime dependency from server requirements
  • Update server requirements documentation
  • Verify cross-platform deployment works on target platforms
Please note: WebView2 is a registered trademark of its respective owner. This site is not affiliated with, endorsed by, or sponsored by Microsoft. 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