How to Migrate from SelectPdf to IronPDF in C#
Migrating from SelectPdf to IronPDF moves your PDF generation workflow off a Windows-only library — whose default rendering engine is an internal WebKit and whose opt-in Blink engine ships with Chromium 124 (April 2024) — onto a current-Chromium, cross-platform library with full CSS3 and JavaScript support. This guide provides a complete, step-by-step migration path that enables deployment to Linux, Docker, Azure Functions, and other cloud platforms that SelectPdf does not support.
Why Migrate from SelectPdf to IronPDF
Understanding SelectPdf
SelectPdf is a commercial library designed to convert HTML content into PDFs using C#. The library is tailored towards developers who require seamless integration of PDF generation functionality within their applications. The strength of SelectPdf lies in its simple API, making it an appealing option for those new to PDF generation.
However, potential users must be aware of its critical limitations. Per the vendor's own documentation, SelectPdf only runs on Windows — not Linux, macOS, or Xamarin. This presents a substantial barrier when considering cloud-based deployment solutions, such as Linux Azure Functions or Docker. The Community Edition is capped at 5 pages per PDF and applies a watermark to every page until a license key is purchased. SelectPdf's default rendering engine is an internal WebKit; the optional Blink engine ships with Chromium 124 (April 2024), which lags current Chrome and can cause issues with newer CSS features such as CSS Grid and the Flexbox gap property.
Critical Limitations of SelectPdf
| Issue | Impact | IronPDF Solution |
|---|---|---|
| Windows-only | Cannot deploy to Linux, Docker, Azure Functions | Full cross-platform support |
| Default WebKit engine; optional Blink ships Chromium 124 (April 2024) | Newer CSS features may fail on the default engine | Up-to-date Chromium |
| 5-page free version limit | Per-page watermark on every page until licensed | Generous trial |
| .NET 10 on Windows only | No Linux/macOS/container deployment | Full .NET 10 across all platforms |
| Cloud deployment blocked (non-Windows) | Can't use AWS Lambda or Linux Azure Functions | Cloud-native |
SelectPdf vs IronPDF Comparison
| Feature | SelectPdf | IronPDF |
|---|---|---|
| Platform Support | Windows Only | Full cross-platform, 10+ distros |
| Modern Web Standards Support | WebKit by default; Blink option ships Chromium 124 (April 2024) | Full CSS3, current Chromium |
| Maximum Free Version Page Limit | 5 pages + per-page watermark | Flexible, no hard limit |
| Pricing | $499 Single Developer to $1,599 Enterprise OEM | Transparent and flexible pricing |
| .NET 10 Support | Yes, but Windows only | Yes, all platforms |
| Deployment in Cloud Environments | Windows targets only | Fully supported (Windows + Linux) |
| CSS Grid | WebKit: limited; Blink (Chromium 124): supported | Supported |
| Flexbox (gap property) | WebKit: not supported; Blink: supported | Supported |
| CSS Variables | WebKit: not supported; Blink: supported | Supported |
| Docker (Linux) | Not supported | Official images |
| Azure Functions (Linux) | Not supported | Supported |
| AWS Lambda | Not supported | Supported |
SelectPdf's NetCore package targets .NET Standard 2.0 and is documented as compatible with .NET 5 through .NET 10 — but only on Windows, which neutralises that compatibility for any team deploying to Linux containers, AWS Lambda, or Linux-based Azure App Service. IronPDF supports the same .NET versions and runs on Windows, Linux, macOS, and Docker.
Before You Start
Prerequisites
- .NET Environment: .NET Framework 4.6.1+ or .NET Core 3.1+ / .NET 5/6/7/8/9/10+
- NuGet Access: Ability to install NuGet packages
- IronPDF License: Obtain your license key from ironpdf.com
NuGet Package Changes
# Remove SelectPdf (use Select.HtmlToPdf.NetCore on .NET Core / .NET 5+)
dotnet remove package Select.HtmlToPdf
# or: dotnet remove package Select.HtmlToPdf.NetCore
# Install IronPDF
dotnet add package IronPdf
# Remove SelectPdf (use Select.HtmlToPdf.NetCore on .NET Core / .NET 5+)
dotnet remove package Select.HtmlToPdf
# or: dotnet remove package Select.HtmlToPdf.NetCore
# Install IronPDF
dotnet add package IronPdf
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"
Complete API Reference
Namespace Changes
// Before: SelectPdf
using SelectPdf;
// After: IronPDF
using IronPdf;
using IronPdf.Engines.Chrome;
// Before: SelectPdf
using SelectPdf;
// After: IronPDF
using IronPdf;
using IronPdf.Engines.Chrome;
' Before: SelectPdf
Imports SelectPdf
' After: IronPDF
Imports IronPdf
Imports IronPdf.Engines.Chrome
Core API Mappings
| SelectPdf | IronPDF | Notes |
|---|---|---|
HtmlToPdf |
ChromePdfRenderer |
Core converter class |
converter.ConvertHtmlString(html) |
renderer.RenderHtmlAsPdf(html) |
HTML string conversion |
converter.ConvertUrl(url) |
renderer.RenderUrlAsPdf(url) |
URL conversion |
doc.Save(path) |
pdf.SaveAs(path) |
Save to file |
doc.Close() |
Not needed | IronPDF handles cleanup |
converter.Options.PdfPageSize |
renderer.RenderingOptions.PaperSize |
Paper size |
converter.Options.PdfPageOrientation |
renderer.RenderingOptions.PaperOrientation |
Orientation |
converter.Options.MarginTop |
renderer.RenderingOptions.MarginTop |
Top margin |
converter.Options.MarginBottom |
renderer.RenderingOptions.MarginBottom |
Bottom margin |
converter.Options.MarginLeft |
renderer.RenderingOptions.MarginLeft |
Left margin |
converter.Options.MarginRight |
renderer.RenderingOptions.MarginRight |
Right margin |
PdfPageSize.A4 |
PdfPaperSize.A4 |
A4 size enum |
PdfPageOrientation.Portrait |
PdfPaperOrientation.Portrait |
Portrait enum |
PdfPageOrientation.Landscape |
PdfPaperOrientation.Landscape |
Landscape enum |
{page_number} |
{page} |
Page number placeholder |
{total_pages} |
{total-pages} |
Total pages placeholder |
Code Migration Examples
Example 1: HTML String to PDF Conversion
Before (SelectPdf):
// NuGet: Install-Package Select.HtmlToPdf
using SelectPdf;
using System;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertHtmlString(htmlContent);
doc.Save("document.pdf");
doc.Close();
Console.WriteLine("PDF generated from HTML string");
}
}
// NuGet: Install-Package Select.HtmlToPdf
using SelectPdf;
using System;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertHtmlString(htmlContent);
doc.Save("document.pdf");
doc.Close();
Console.WriteLine("PDF generated from HTML string");
}
}
Imports SelectPdf
Imports System
Class Program
Shared Sub Main()
Dim htmlContent As String = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"
Dim converter As New HtmlToPdf()
Dim doc As PdfDocument = converter.ConvertHtmlString(htmlContent)
doc.Save("document.pdf")
doc.Close()
Console.WriteLine("PDF generated from HTML string")
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("document.pdf");
Console.WriteLine("PDF generated from HTML string");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
string htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("document.pdf");
Console.WriteLine("PDF generated from HTML string");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim htmlContent As String = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("document.pdf")
Console.WriteLine("PDF generated from HTML string")
End Sub
End Class
This example demonstrates the core API differences. SelectPdf uses HtmlToPdf as the converter class, calling ConvertHtmlString() to create a PdfDocument, then Save() and Close() to persist and clean up.
IronPDF uses ChromePdfRenderer with RenderHtmlAsPdf(), returning a PdfDocument that's saved with SaveAs(). The Close() call is eliminated—IronPDF handles resource management automatically. See the HTML to PDF documentation for comprehensive examples.
Example 2: URL to PDF Conversion
Before (SelectPdf):
// NuGet: Install-Package Select.HtmlToPdf
using SelectPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertUrl("https://www.example.com");
doc.Save("output.pdf");
doc.Close();
Console.WriteLine("PDF created successfully");
}
}
// NuGet: Install-Package Select.HtmlToPdf
using SelectPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf converter = new HtmlToPdf();
PdfDocument doc = converter.ConvertUrl("https://www.example.com");
doc.Save("output.pdf");
doc.Close();
Console.WriteLine("PDF created successfully");
}
}
Imports SelectPdf
Imports System
Class Program
Shared Sub Main()
Dim converter As New HtmlToPdf()
Dim doc As PdfDocument = converter.ConvertUrl("https://www.example.com")
doc.Save("output.pdf")
doc.Close()
Console.WriteLine("PDF created successfully")
End Sub
End Class
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("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.RenderUrlAsPdf("https://www.example.com");
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.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("output.pdf")
Console.WriteLine("PDF created successfully")
End Sub
End Class
SelectPdf's ConvertUrl() method maps directly to IronPDF's RenderUrlAsPdf(). The critical difference is in the rendering engine: SelectPdf defaults to an internal WebKit and offers an opt-in Blink engine bundled with Chromium 124 (April 2024), while IronPDF uses current stable Chromium for full CSS3 and JavaScript support. Learn more in our tutorials.
Example 3: Custom Page Settings and Margins
Before (SelectPdf):
// NuGet: Install-Package Select.HtmlToPdf
using SelectPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf converter = new HtmlToPdf();
converter.Options.PdfPageSize = PdfPageSize.A4;
converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait;
converter.Options.MarginTop = 20;
converter.Options.MarginBottom = 20;
converter.Options.MarginLeft = 20;
converter.Options.MarginRight = 20;
string html = "<html><body><h1>Custom Page Settings</h1></body></html>";
PdfDocument doc = converter.ConvertHtmlString(html);
doc.Save("custom-settings.pdf");
doc.Close();
Console.WriteLine("PDF with custom settings created");
}
}
// NuGet: Install-Package Select.HtmlToPdf
using SelectPdf;
using System;
class Program
{
static void Main()
{
HtmlToPdf converter = new HtmlToPdf();
converter.Options.PdfPageSize = PdfPageSize.A4;
converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait;
converter.Options.MarginTop = 20;
converter.Options.MarginBottom = 20;
converter.Options.MarginLeft = 20;
converter.Options.MarginRight = 20;
string html = "<html><body><h1>Custom Page Settings</h1></body></html>";
PdfDocument doc = converter.ConvertHtmlString(html);
doc.Save("custom-settings.pdf");
doc.Close();
Console.WriteLine("PDF with custom settings created");
}
}
Imports SelectPdf
Imports System
Module Program
Sub Main()
Dim converter As New HtmlToPdf()
converter.Options.PdfPageSize = PdfPageSize.A4
converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait
converter.Options.MarginTop = 20
converter.Options.MarginBottom = 20
converter.Options.MarginLeft = 20
converter.Options.MarginRight = 20
Dim html As String = "<html><body><h1>Custom Page Settings</h1></body></html>"
Dim doc As PdfDocument = converter.ConvertHtmlString(html)
doc.Save("custom-settings.pdf")
doc.Close()
Console.WriteLine("PDF with custom settings created")
End Sub
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
string html = "<html><body><h1>Custom Page Settings</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom-settings.pdf");
Console.WriteLine("PDF with custom settings created");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
string html = "<html><body><h1>Custom Page Settings</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom-settings.pdf");
Console.WriteLine("PDF with custom settings created");
}
}
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports System
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Portrait
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim html As String = "<html><body><h1>Custom Page Settings</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("custom-settings.pdf")
Console.WriteLine("PDF with custom settings created")
End Sub
End Module
The page settings pattern is nearly identical, with straightforward property name changes:
converter.Options.PdfPageSize→renderer.RenderingOptions.PaperSizeconverter.Options.PdfPageOrientation→renderer.RenderingOptions.PaperOrientationPdfPageSize.A4→PdfPaperSize.A4PdfPageOrientation.Portrait→PdfPaperOrientation.Portrait
Margin properties maintain the same names and units.
The Windows-Only Problem
SelectPdf's Platform Limitation
Despite any marketing claims, SelectPdf explicitly does not support:
- Linux (any distribution)
- macOS
- Docker containers
- Azure Functions
- AWS Lambda
- Google Cloud Functions
- Any ARM-based systems
This is a fundamental architectural limitation—SelectPdf depends on Windows-specific libraries and cannot be ported.
Platform Support Comparison
| Platform | SelectPdf | IronPDF |
|---|---|---|
| Windows Server 2019+ | ✅ | ✅ |
| Windows 10/11 | ✅ | ✅ |
| Ubuntu 20.04+ | ❌ | ✅ |
| Debian 10+ | ❌ | ✅ |
| CentOS 7+ | ❌ | ✅ |
| Alpine Linux | ❌ | ✅ |
| Amazon Linux 2 | ❌ | ✅ |
| macOS 10.15+ | ❌ | ✅ |
| Azure App Service (Linux) | ❌ | ✅ |
| Azure Functions | ❌ | ✅ |
| AWS Lambda | ❌ | ✅ |
| Docker (Linux) | ❌ | ✅ |
| Kubernetes | ❌ | ✅ |
The Outdated Rendering Engine
CSS Feature Support Comparison
SelectPdf ships three engines (per vendor docs): an internal WebKit (the default), Blink (introduced in v19.1, bundled with Chromium 124.0.6367.201 — released April 2024), and Chromium/CEF. The default WebKit engine has not kept pace with modern web standards:
| CSS Feature | SelectPdf (WebKit default) | SelectPdf (Blink, Chromium 124) | IronPDF |
|---|---|---|---|
| CSS Grid | ⚠ Partial/broken | ✅ | ✅ Full |
| Flexbox (basic) | ✅ | ✅ | ✅ |
| Flexbox (gap property) | ❌ | ✅ | ✅ |
| CSS Variables | ❌ | ✅ | ✅ |
| CSS calc() | ⚠ Limited | ✅ | ✅ |
| @media print | ⚠ Limited | ✅ | ✅ |
| @font-face | ⚠ Limited | ✅ | ✅ |
| Web Fonts | ⚠ Limited | ✅ | ✅ |
| SVG | ⚠ Basic | ✅ | ✅ Full |
| CSS Transforms | ⚠ Limited | ✅ | ✅ |
| CSS Animations | ❌ | ⚠ Partial | ✅ |
New Capabilities After Migration
After migrating to IronPDF, you gain capabilities that SelectPdf cannot provide:
Cross-Platform Deployment
// ✅ IronPDF - Works everywhere
using IronPdf;
// Azure App Service (Linux) - WORKS
// Docker container - WORKS
// AWS Lambda - WORKS
// GitHub Actions on ubuntu-latest - WORKS
// macOS development - WORKS
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello</h1>");
pdf.SaveAs("output.pdf");
// ✅ IronPDF - Works everywhere
using IronPdf;
// Azure App Service (Linux) - WORKS
// Docker container - WORKS
// AWS Lambda - WORKS
// GitHub Actions on ubuntu-latest - WORKS
// macOS development - WORKS
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello</h1>");
pdf.SaveAs("output.pdf");
' ✅ IronPDF - Works everywhere
Imports IronPdf
' Azure App Service (Linux) - WORKS
' Docker container - WORKS
' AWS Lambda - WORKS
' GitHub Actions on ubuntu-latest - WORKS
' macOS development - WORKS
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello</h1>")
pdf.SaveAs("output.pdf")
Modern CSS Support
// ✅ IronPDF - Uses latest stable Chromium
var renderer = new ChromePdfRenderer();
var html = @"
<style>
:root { --primary: #007bff; --gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--gap); }
</style>
<div class='grid'>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 1</div>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 2</div>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// All modern CSS features render correctly!
// ✅ IronPDF - Uses latest stable Chromium
var renderer = new ChromePdfRenderer();
var html = @"
<style>
:root { --primary: #007bff; --gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--gap); }
</style>
<div class='grid'>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 1</div>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 2</div>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// All modern CSS features render correctly!
' ✅ IronPDF - Uses latest stable Chromium
Dim renderer As New ChromePdfRenderer()
Dim html As String = "
<style>
:root { --primary: #007bff; --gap: 20px; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--gap); }
</style>
<div class='grid'>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 1</div>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 2</div>
<div style='background: var(--primary); color: white; padding: 1rem;'>Item 3</div>
</div>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
' All modern CSS features render correctly!
No Close() Required
IronPDF handles resource management automatically:
// Option 1: Let garbage collection handle it
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No Close() needed
// Option 2: Explicit disposal
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
}
// Option 1: Let garbage collection handle it
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// No Close() needed
// Option 2: Explicit disposal
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
}
' Option 1: Let garbage collection handle it
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
' No Close() needed
' Option 2: Explicit disposal
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Using
Migration Checklist
Pre-Migration
- Audit all SelectPdf usages in codebase
- Document current converter options for mapping
- Identify header/footer implementations
- Check page number placeholder syntax (
{page_number}→{page}) - Note base URL handling patterns
- Verify target deployment platforms
- Obtain IronPDF license key from ironpdf.com
Code Updates
- Remove
Select.HtmlToPdfNuGet package - Install
IronPdfNuGet package - Update namespace imports (
using SelectPdf;→using IronPdf;) - Replace
HtmlToPdfwithChromePdfRenderer - Replace
ConvertHtmlString()withRenderHtmlAsPdf() - Replace
ConvertUrl()withRenderUrlAsPdf() - Update option property names (
Options.PdfPageSize→RenderingOptions.PaperSize) - Convert
PdfPageSizetoPdfPaperSize - Convert
PdfPageOrientationtoPdfPaperOrientation - Replace
doc.Save()withpdf.SaveAs() - Remove all
doc.Close()calls - Fix page number placeholders (
{page_number}→{page},{total_pages}→{total-pages}) - Add license initialization at application startup
Post-Migration
- Run all unit tests
- Verify CSS rendering (especially Grid/Flexbox)
- Test JavaScript execution
- Verify header/footer page numbers
- Test on target platforms (Linux, Docker, etc.)
- Performance test
- Compare PDF output quality
- Update CI/CD pipelines
- Test cloud deployments (if applicable)

