푸터 콘텐츠로 바로가기
MIGRATION GUIDES

How to Migrate from Playwright to IronPDF in C#

Migrating from Playwright for .NET to IronPDF transforms your PDF generation workflow from a testing-centric browser automation tool to a purpose-built PDF library. This guide provides a complete, step-by-step migration path that eliminates complex async patterns, browser lifecycle management, and 400MB+ browser downloads while providing better performance and professional PDF features.

Why Migrate from Playwright to IronPDF

Understanding Playwright for .NET

Playwright for .NET is Microsoft's end-to-end testing framework, NOT a document generation library. It was built from the ground up for automated testing across Chromium, Firefox, and WebKit browsers. Playwright excels at testing scenarios: clicking buttons, filling forms, intercepting network requests, taking screenshots, and validating cross-browser compatibility.

Critical Understanding: Playwright is a testing tool being repurposed for PDF generation. PDF creation is merely a side effect of the browser's print functionality (Ctrl+P), not a primary design goal. This creates fundamental architectural mismatches:

  • Testing-first architecture: Built for interactive browser testing, not headless document production
  • Multi-browser overhead: Downloads 400MB+ of browser binaries (Chromium, Firefox, WebKit) even when you only need PDF generation
  • Test-centric API: Complex async patterns designed for test automation workflows, not document generation
  • No document features: Missing PDF/A compliance, digital signatures, watermarking, merging, security controls

The Testing Framework Problem

Playwright was designed for end-to-end testing, not document generation. This creates fundamental issues when using it for PDFs:

  1. 400MB+ browser downloads required before first use. Playwright's default configuration involves downloading multiple browsers, which can be a consideration for environments with strict resource constraints.

  2. Complex async patterns with browser contexts and page management. Developers must gain familiarity with browser contexts and page management, along with proper disposal practices.

  3. Testing-first architecture not optimized for document generation.

  4. Print-to-PDF limitations equivalent to Ctrl+P browser print. Layouts may reflow, backgrounds may be omitted by default, and output is paginated for printing.

  5. No PDF/A or PDF/UA support for accessibility compliance. Playwright cannot produce PDF/A (archival) or PDF/UA (accessibility) compliant documents. For Section 508, EU accessibility directives, or long-term archival requirements, you'll need a dedicated PDF library.

  6. Resource-heavy operations requiring full browser instances.

The Testing Framework Configuration Problem

Playwright requires extensive testing-centric configuration that QA engineers understand but document developers shouldn't need:

Browser Installation Required:

# Manual installation step required before first use
playwright install  # Downloads 400MB+ of browser binaries
# Or programmatically:
playwright install chromium  # Still 100MB+ for single browser
# Manual installation step required before first use
playwright install  # Downloads 400MB+ of browser binaries
# Or programmatically:
playwright install chromium  # Still 100MB+ for single browser
SHELL

Browser Launch Configuration:

// Testing-focused launch options for PDF generation
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
    Headless = true,  // Required for server environments
    Args = new[] { "--disable-gpu", "--no-sandbox" } // Linux/Docker configs
});
// Testing-focused launch options for PDF generation
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
    Headless = true,  // Required for server environments
    Args = new[] { "--disable-gpu", "--no-sandbox" } // Linux/Docker configs
});
$vbLabelText   $csharpLabel

Testing-Specific Configuration Options:

  • Headless: Must configure headless mode for production (defaults to headed for testing)
  • SlowMo: Test timing delays (irrelevant for PDF generation)
  • Devtools: Testing tools configuration (not needed for documents)
  • ExecutablePath: Custom browser paths for test environments
  • Proxy: Network interception for testing (unnecessary overhead)
  • DownloadsPath: Test artifact management
  • TracesDir: Test execution traces

Browser Context Management:

// Complex context lifecycle from testing paradigm
var context = await browser.NewContextAsync(new BrowserNewContextOptions
{
    ViewportSize = new ViewportSize { Width = 1920, Height = 1080 },
    UserAgent = "custom-user-agent",
    Locale = "en-US",
    TimezoneId = "America/New_York"
});
var page = await context.NewPageAsync();
// ... generate PDF ...
await context.CloseAsync();  // Manual cleanup required
await browser.CloseAsync();  // Manual cleanup required
// Complex context lifecycle from testing paradigm
var context = await browser.NewContextAsync(new BrowserNewContextOptions
{
    ViewportSize = new ViewportSize { Width = 1920, Height = 1080 },
    UserAgent = "custom-user-agent",
    Locale = "en-US",
    TimezoneId = "America/New_York"
});
var page = await context.NewPageAsync();
// ... generate PDF ...
await context.CloseAsync();  // Manual cleanup required
await browser.CloseAsync();  // Manual cleanup required
$vbLabelText   $csharpLabel

Multi-Browser Complexity:

// Playwright downloads multiple browsers by default
await playwright.Chromium.LaunchAsync();  // For Chrome testing
await playwright.Firefox.LaunchAsync();   // For Firefox testing
await playwright.Webkit.LaunchAsync();    // For Safari testing
// All downloaded but only Chromium needed for PDF generation
// Playwright downloads multiple browsers by default
await playwright.Chromium.LaunchAsync();  // For Chrome testing
await playwright.Firefox.LaunchAsync();   // For Firefox testing
await playwright.Webkit.LaunchAsync();    // For Safari testing
// All downloaded but only Chromium needed for PDF generation
$vbLabelText   $csharpLabel

IronPDF: Zero Configuration, Zero Installation

// No installation, no configuration, no lifecycle management
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No installation, no configuration, no lifecycle management
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
$vbLabelText   $csharpLabel

True plug-and-play: IronPDF eliminates all testing framework overhead. No browser installation commands, no headless configuration, no context management—just instantiate and render. Built specifically for document generation, not adapted from testing tools.

Playwright vs IronPDF Performance Comparison

Metric Playwright IronPDF
Primary Purpose E2E Testing Framework PDF Document Generation
Design Philosophy Testing tool with PDF side feature Purpose-built PDF library
Installation Required playwright install (400MB+ download) None - instant setup
Configuration Required Headless mode, browser launch options, contexts Zero configuration
Browser Download 400MB+ (Chromium, Firefox, WebKit) Built-in optimized engine
Setup Complexity Command-line install + launch configuration Plug-and-play
First Render (Cold Start) 4.5 seconds 2.8 seconds
Subsequent Renders 3.8-4.1 seconds 0.8-1.2 seconds
Memory per Conversion 280-420MB 80-120MB
API Complexity Complex async browser/context/page lifecycle Simple synchronous one-liners
Initialization CreateAsync() + LaunchAsync() + NewPageAsync() new ChromePdfRenderer()
PDF/A Support Not available Supported
PDF/UA Accessibility Not available Supported
Digital Signatures Not available Supported
PDF Editing Not available Merge, split, stamp, edit
Professional Support Community Commercial with SLA

IronPDF was built with a focus on PDF generation. Unlike the testing-centric Playwright, IronPDF provides a variety of document-centric API features. It relies on a single optimized Chromium instance, favoring efficiency and offering both synchronous and asynchronous operations. This results in a simpler mental model and workflow for developers who require PDF functionalities.

For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a purpose-built PDF solution that eliminates browser automation overhead while delivering better performance and professional document features.

The Bottom Line

Playwright is Microsoft's testing framework designed for QA engineers running cross-browser automated tests. Using it for PDF generation is architectural mismatch that requires extensive testing-specific knowledge:

  • Manual browser installation (playwright install)
  • Headless mode configuration for production
  • Browser launch option management
  • Context lifecycle configuration
  • Multi-browser downloads (400MB+) when only one is needed
  • Complex async/await patterns from testing paradigm

IronPDF is a document generation library designed for developers building PDF workflows. It's truly plug-and-play:

  • Zero installation—works immediately
  • Zero configuration—intelligent defaults
  • Zero browser downloads—optimized engine included
  • Simple API—no testing concepts to learn
  • Automatic resource management—no lifecycle complexity

If you need to test web applications across browsers, use Playwright. If you need to generate PDF documents, use IronPDF. Don't adapt a testing framework for document generation—use the tool built specifically for the job.


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 Playwright
dotnet remove package Microsoft.Playwright

# Remove browser binaries (reclaim ~400MB disk space)
# Delete the .playwright folder in your project or user directory

# Add IronPDF
dotnet add package IronPdf
# Remove Playwright
dotnet remove package Microsoft.Playwright

# Remove browser binaries (reclaim ~400MB disk space)
# Delete the .playwright folder in your project or user directory

# Add IronPDF
dotnet add package IronPdf
SHELL

No playwright install required with IronPDF - the rendering engine is bundled automatically.

License Configuration

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

Complete API Reference

Namespace Changes

// Before: Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
// Before: Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

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

Core API Mappings

Playwright API IronPDF API
Playwright.CreateAsync() new ChromePdfRenderer()
playwright.Chromium.LaunchAsync() Not needed
browser.NewPageAsync() Not needed
page.GotoAsync(url) renderer.RenderUrlAsPdf(url)
page.SetContentAsync(html) + page.PdfAsync() renderer.RenderHtmlAsPdf(html)
page.CloseAsync() Not needed
browser.CloseAsync() Not needed
PagePdfOptions.Format RenderingOptions.PaperSize
PagePdfOptions.Margin RenderingOptions.MarginTop/Bottom/Left/Right
PagePdfOptions.DisplayHeaderFooter RenderingOptions.TextHeader/TextFooter
PagePdfOptions.HeaderTemplate RenderingOptions.HtmlHeader
PagePdfOptions.FooterTemplate RenderingOptions.HtmlFooter
<span class='pageNumber'> {page}

Code Migration Examples

Example 1: HTML String to PDF Conversion

Before (Playwright):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        await page.SetContentAsync(html);
        await page.PdfAsync(new PagePdfOptions { Path = "output.pdf" });

        await browser.CloseAsync();
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        await page.SetContentAsync(html);
        await page.PdfAsync(new PagePdfOptions { Path = "output.pdf" });

        await browser.CloseAsync();
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        string html = "<h1>Hello World</h1><p>This is a test PDF.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

This example demonstrates the fundamental architectural difference. Playwright requires five async operations: Playwright.CreateAsync(), Chromium.LaunchAsync(), NewPageAsync(), SetContentAsync(), and PdfAsync(), plus explicit browser cleanup with CloseAsync().

IronPDF eliminates all this complexity: create a ChromePdfRenderer, call RenderHtmlAsPdf(), and SaveAs(). No async patterns, no browser lifecycle, no cleanup code. IronPDF's approach offers cleaner syntax and better integration with modern .NET applications. See the HTML to PDF documentation for comprehensive examples.

Example 2: URL to PDF Conversion

Before (Playwright):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        await page.GotoAsync("https://www.example.com");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "webpage.pdf",
            Format = "A4"
        });

        await browser.CloseAsync();
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        await page.GotoAsync("https://www.example.com");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "webpage.pdf",
            Format = "A4"
        });

        await browser.CloseAsync();
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

Playwright uses GotoAsync() to navigate to a URL followed by PdfAsync(). IronPDF provides a single RenderUrlAsPdf() method that handles navigation and PDF generation in one call. Note that Playwright requires specifying the Format in PagePdfOptions, while IronPDF uses RenderingOptions.PaperSize for paper size configuration. Learn more in our tutorials.

Example 3: Custom Page Size with Margins

Before (Playwright):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var playwright = await Playwright.CreateAsync();
        await using var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();
        await page.SetContentAsync("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "custom.pdf",
            Format = "Letter",
            Margin = new Margin { Top = "1in", Bottom = "1in", Left = "0.5in", Right = "0.5in" }
        });
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var playwright = await Playwright.CreateAsync();
        await using var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();
        await page.SetContentAsync("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        await page.PdfAsync(new PagePdfOptions 
        { 
            Path = "custom.pdf",
            Format = "Letter",
            Margin = new Margin { Top = "1in", Bottom = "1in", Left = "0.5in", Right = "0.5in" }
        });
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// 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 = 25;
        renderer.RenderingOptions.MarginBottom = 25;
        renderer.RenderingOptions.MarginLeft = 12;
        renderer.RenderingOptions.MarginRight = 12;
        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        pdf.SaveAs("custom.pdf");
    }
}
// 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 = 25;
        renderer.RenderingOptions.MarginBottom = 25;
        renderer.RenderingOptions.MarginLeft = 12;
        renderer.RenderingOptions.MarginRight = 12;
        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Letter size with margins</p>");
        pdf.SaveAs("custom.pdf");
    }
}
$vbLabelText   $csharpLabel

Playwright uses string-based margin values ("1in", "0.5in") while IronPDF uses numeric millimeter values. The conversion is: 1 inch = 25.4mm, so "1in" becomes 25 and "0.5in" becomes approximately 12. Playwright's Format = "Letter" maps to IronPDF's PaperSize = PdfPaperSize.Letter.

Example 4: Headers, Footers, and Custom Settings

Before (Playwright):

// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        await page.SetContentAsync(html);

        await page.PdfAsync(new PagePdfOptions
        {
            Path = "custom.pdf",
            Format = "A4",
            Margin = new Margin { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" },
            DisplayHeaderFooter = true,
            HeaderTemplate = "<div style='font-size:10px; text-align:center;'>Header</div>",
            FooterTemplate = "<div style='font-size:10px; text-align:center;'>Page <span class='pageNumber'></span></div>"
        });

        await browser.CloseAsync();
    }
}
// NuGet: Install-Package Microsoft.Playwright
using Microsoft.Playwright;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        var playwright = await Playwright.CreateAsync();
        var browser = await playwright.Chromium.LaunchAsync();
        var page = await browser.NewPageAsync();

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        await page.SetContentAsync(html);

        await page.PdfAsync(new PagePdfOptions
        {
            Path = "custom.pdf",
            Format = "A4",
            Margin = new Margin { Top = "1cm", Bottom = "1cm", Left = "1cm", Right = "1cm" },
            DisplayHeaderFooter = true,
            HeaderTemplate = "<div style='font-size:10px; text-align:center;'>Header</div>",
            FooterTemplate = "<div style='font-size:10px; text-align:center;'>Page <span class='pageNumber'></span></div>"
        });

        await browser.CloseAsync();
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

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

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.TextHeader.CenterText = "Header";
        renderer.RenderingOptions.TextFooter.CenterText = "Page {page}";

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.TextHeader.CenterText = "Header";
        renderer.RenderingOptions.TextFooter.CenterText = "Page {page}";

        string html = "<h1>Custom PDF</h1><p>With margins and headers.</p>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
$vbLabelText   $csharpLabel

This example shows the header/footer placeholder syntax difference. Playwright uses HTML class-based placeholders (<span class='pageNumber'></span>), while IronPDF uses curly brace placeholders ({page}). Note that Playwright requires DisplayHeaderFooter = true to enable headers/footers, while IronPDF enables them automatically when you set header/footer content.


Critical Migration Notes

Async to Sync Conversion

Playwright requires async/await throughout; IronPDF supports synchronous operations:

// Playwright: Async required
public async Task<byte[]> GeneratePdfAsync(string html)
{
    using var playwright = await Playwright.CreateAsync();
    await using var browser = await playwright.Chromium.LaunchAsync();
    var page = await browser.NewPageAsync();
    await page.SetContentAsync(html);
    return await page.PdfAsync();
}

// IronPDF: Sync is simpler
public byte[] GeneratePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}
// Playwright: Async required
public async Task<byte[]> GeneratePdfAsync(string html)
{
    using var playwright = await Playwright.CreateAsync();
    await using var browser = await playwright.Chromium.LaunchAsync();
    var page = await browser.NewPageAsync();
    await page.SetContentAsync(html);
    return await page.PdfAsync();
}

// IronPDF: Sync is simpler
public byte[] GeneratePdf(string html)
{
    var renderer = new ChromePdfRenderer();
    return renderer.RenderHtmlAsPdf(html).BinaryData;
}
$vbLabelText   $csharpLabel

Margin Unit Conversion

Playwright uses string units; IronPDF uses numeric millimeters:

Playwright IronPDF (mm)
"1in" 25
"0.5in" 12
"1cm" 10
Playwright Class IronPDF Placeholder
<span class='pageNumber'> {page}
<span class='totalPages'> {total-pages}
<span class='date'> {date}
<span class='title'> {html-title}

Browser Lifecycle Elimination

Remove all browser management code:

// Playwright: Explicit cleanup required
await page.CloseAsync();
await browser.CloseAsync();
playwright.Dispose();

// IronPDF: No disposal needed - just use the renderer
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Playwright: Explicit cleanup required
await page.CloseAsync();
await browser.CloseAsync();
playwright.Dispose();

// IronPDF: No disposal needed - just use the renderer
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
$vbLabelText   $csharpLabel

New Capabilities After Migration

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

PDF Merging

var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.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>");
$vbLabelText   $csharpLabel

Password Protection

pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "readonly";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "readonly";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
$vbLabelText   $csharpLabel

Digital Signatures

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

PDF/A Compliance

pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
$vbLabelText   $csharpLabel

Migration Checklist

Pre-Migration

  • Identify all Playwright PDF generation code
  • Document margin values (convert inches/cm to millimeters)
  • Note header/footer placeholder syntax for conversion
  • Obtain IronPDF license key from ironpdf.com

Package Changes

  • Remove Microsoft.Playwright NuGet package
  • Delete .playwright folder to reclaim ~400MB disk space
  • Install IronPdf NuGet package: dotnet add package IronPdf

Code Changes

  • Update namespace imports
  • Replace async browser lifecycle with ChromePdfRenderer
  • Convert page.SetContentAsync() + page.PdfAsync() to RenderHtmlAsPdf()
  • Convert page.GotoAsync() + page.PdfAsync() to RenderUrlAsPdf()
  • Convert margin strings to millimeter values
  • Convert header/footer placeholder syntax
  • Remove all browser/page disposal code
  • Add license initialization at application startup

Post-Migration

  • Visual comparison of PDF output
  • Verify header/footer rendering with page numbers
  • Test margin and page sizing accuracy
  • Add new capabilities (security, watermarks, merging) as needed

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.