DEV Community

IronSoftware
IronSoftware

Posted on

Migrating from QuestPDF to IronPDF (.NET Guide)

QuestPDF is excellent for code-first PDF generation with its elegant fluent API, but it has a critical limitation: no HTML-to-PDF conversion. If your project needs to render web content, HTML templates, or modern CSS frameworks to PDF, IronPDF is purpose-built for this use case.

Here's when and how to migrate from Quest PDF to IronPDF.

Why Migrate from QuestPDF to IronPDF?

1. No HTML-to-PDF Support in QuestPDF

QuestPDF is designed for programmatic, code-first PDF generation. You define layouts using C# code:

using QuestPDF.Fluent;
using QuestPDF.Helpers;
// Install via NuGet: Install-Package QuestPDF

Document.Create(container =>
{
    container.Page(page =>
    {
        page.Content()
            .PaddingVertical(20)
            .Column(column =>
            {
                column.Item().Text("Hello from QuestPDF").FontSize(20);
            });
    });
}).GeneratePdf("output.pdf");
Enter fullscreen mode Exit fullscreen mode

This works great for structured layouts (invoices, reports, badges) but breaks down when you need HTML rendering.

If you have HTML templates, Bootstrap layouts, or dynamically generated web content, QuestPDF can't help you. You'd need to manually recreate every HTML element in QuestPDF's fluent API—an unscalable approach.

IronPDF handles HTML natively:

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

var html = "<h1>Hello from IronPDF</h1>";
var renderer = new [ChromePdfRenderer](https://ironpdf.com/blog/videos/how-to-render-html-string-to-pdf-in-csharp-ironpdf/)();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Enter fullscreen mode Exit fullscreen mode

2. Modern CSS/JavaScript Support

IronPDF uses Chromium rendering, so modern web standards work perfectly:

  • Flexbox and CSS Grid
  • Bootstrap, Tailwind, and other CSS frameworks
  • JavaScript execution (for charts, SPAs, dynamic content)
  • Web fonts (Google Fonts, custom fonts)

QuestPDF doesn't support any of this. It's not a Chromium rendering engine—it's a programmatic layout library.

IronPDF with Bootstrap:

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

var html = @"
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<div class='container'>
    <div class='alert alert-success'>Bootstrap works!</div>
</div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("bootstrap.pdf");
Enter fullscreen mode Exit fullscreen mode

This is impossible with QuestPDF's code-first approach.

3. Existing PDF Manipulation

QuestPDF excels at generating PDFs but lacks support for manipulating existing PDFs (merging, splitting, extracting text, filling forms).

IronPDF supports comprehensive PDF manipulation:

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

// [Merge PDFs](https://ironpdf.com/java/how-to/java-merge-pdf-tutorial/)
var pdf1 = PdfDocument.FromFile("doc1.pdf");
var pdf2 = PdfDocument.FromFile("doc2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("combined.pdf");

// Extract text
var text = pdf1.ExtractAllText();

// Fill forms
pdf1.Form.SetFieldValue("name", "John Doe");
Enter fullscreen mode Exit fullscreen mode

QuestPDF can't do any of this.

When to Stay with QuestPDF

Don't migrate if:

  1. You don't need HTML rendering: QuestPDF's fluent API is great for code-first layouts
  2. Your PDFs are highly structured (invoices, certificates, badges) with no HTML templates
  3. You prefer code over markup: Some developers prefer defining layouts in C# rather than HTML
  4. Free/open-source is required: QuestPDF is MIT-licensed for non-commercial use (< $2M revenue)

Migrate to IronPDF if:

  1. You need HTML-to-PDF conversion: This is IronPDF's core strength
  2. You use HTML templates (Razor, Blazor, static HTML)
  3. You need modern CSS/JavaScript support: Bootstrap, Tailwind, charts, etc.
  4. You need to manipulate existing PDFs: Merge, split, extract, fill forms

Key Differences: QuestPDF vs. IronPDF

Feature QuestPDF IronPDF
HTML to PDF ❌ Not supported ⭐⭐⭐⭐⭐ Chromium-based
Modern CSS (Flexbox, Grid) ❌ Not supported ✅ Fully supported
JavaScript Execution ❌ Not supported ✅ Fully supported
Code-First Fluent API ⭐⭐⭐⭐⭐ Excellent ❌ Not applicable
PDF Manipulation (merge, split) ❌ Not supported ✅ Fully supported
Extract Text from PDFs ❌ Not supported ✅ Supported
Fill PDF Forms ❌ Not supported ✅ Supported
Digital Signatures ❌ Limited ✅ Fully supported
Licensing MIT (< $2M revenue) Commercial $749+
Learning Curve Moderate (fluent API) Easy (HTML-based)

Migration Strategy: When Both Libraries Make Sense

In many cases, you don't need to fully migrate—you can use both libraries together.

Use QuestPDF for:

  • Programmatic layouts (invoices, tickets, badges)
  • PDFs built entirely from code

Use IronPDF for:

  • HTML-to-PDF conversion
  • Web content rendering
  • PDF manipulation (merge, split, extract)

Hybrid approach example:

using IronPdf;
using QuestPDF.Fluent;
// Install via NuGet: Install-Package IronPdf and QuestPDF

// Generate invoice with QuestPDF
Document.Create(container =>
{
    container.Page(page =>
    {
        page.Content().Text("Invoice #12345");
    });
}).GeneratePdf("invoice-questpdf.pdf");

// Generate web content with IronPDF
var renderer = new ChromePdfRenderer();
var webPdf = renderer.RenderHtmlAsPdf("<h1>Web Content</h1>");
webPdf.SaveAs("web-content.pdf");

// Merge both PDFs with IronPDF
var invoicePdf = PdfDocument.FromFile("invoice-questpdf.pdf");
var finalPdf = PdfDocument.Merge(invoicePdf, webPdf);
finalPdf.SaveAs("final-document.pdf");
Enter fullscreen mode Exit fullscreen mode

This approach leverages QuestPDF's fluent API for structured layouts and IronPDF for HTML rendering—best of both worlds.

Full Migration: QuestPDF to IronPDF

If you want to fully migrate to IronPDF (eliminating QuestPDF dependency), you'll need to convert your code-first layouts to HTML templates.

Step 1: Convert QuestPDF Layouts to HTML

Before (QuestPDF):

using QuestPDF.Fluent;
using QuestPDF.Helpers;
// Install via NuGet: Install-Package QuestPDF

Document.Create(container =>
{
    container.Page(page =>
    {
        page.Content()
            .Padding(20)
            .Column(column =>
            {
                column.Item().Text("Invoice").FontSize(24).Bold();
                column.Item().Text("Total: $500").FontSize(16);
            });
    });
}).GeneratePdf("invoice.pdf");
Enter fullscreen mode Exit fullscreen mode

After (IronPDF with HTML):

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

var html = @"
<div style='padding: 20px;'>
    <h1 style='font-size: 24px; font-weight: bold;'>Invoice</h1>
    <p style='font-size: 16px;'>Total: $500</p>
</div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("invoice.pdf");
Enter fullscreen mode Exit fullscreen mode

Trade-off:

QuestPDF's fluent API is type-safe and compile-time checked. HTML strings are runtime-validated. Use templating engines (Razor, Scriban) to maintain type safety.

Step 2: Use Razor Templates for Type Safety

Razor view (Invoice.cshtml):

@model InvoiceModel

<div style="padding: 20px;">
    <h1 style="font-size: 24px; font-weight: bold;">Invoice</h1>
    <p>Customer: @Model.CustomerName</p>
    <p>Total: @Model.Total.ToString("C")</p>
</div>
Enter fullscreen mode Exit fullscreen mode

C# code:

using IronPdf;
using Microsoft.AspNetCore.Mvc.Razor;
// Install via NuGet: Install-Package IronPdf

// Render Razor view to HTML string (using RazorEngine or ASP.NET Core)
var html = RenderRazorView("Invoice.cshtml", invoiceModel);

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("invoice.pdf");
Enter fullscreen mode Exit fullscreen mode

This approach gives you type safety (via Razor models) while leveraging IronPDF's HTML rendering.

Step 3: Migrate Tables

Before (QuestPDF):

using QuestPDF.Fluent;
using QuestPDF.Helpers;
// Install via NuGet: Install-Package QuestPDF

Document.Create(container =>
{
    container.Page(page =>
    {
        page.Content()
            .Table(table =>
            {
                table.ColumnsDefinition(columns =>
                {
                    columns.RelativeColumn();
                    columns.RelativeColumn();
                });

                table.Cell().Text("Product");
                table.Cell().Text("Price");
                table.Cell().Text("Widget");
                table.Cell().Text("$10");
            });
    });
}).GeneratePdf("table.pdf");
Enter fullscreen mode Exit fullscreen mode

After (IronPDF with HTML table):

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

var html = @"
<table style='width: 100%; border-collapse: collapse;'>
    <tr>
        <th style='border: 1px solid #000; padding: 8px;'>Product</th>
        <th style='border: 1px solid #000; padding: 8px;'>Price</th>
    </tr>
    <tr>
        <td style='border: 1px solid #000; padding: 8px;'>Widget</td>
        <td style='border: 1px solid #000; padding: 8px;'>$10</td>
    </tr>
</table>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("table.pdf");
Enter fullscreen mode Exit fullscreen mode

HTML tables are more flexible and support CSS frameworks (Bootstrap, Tailwind).

Step 4: Migrate Headers and Footers

Before (QuestPDF):

using QuestPDF.Fluent;
using QuestPDF.Helpers;
// Install via NuGet: Install-Package QuestPDF

Document.Create(container =>
{
    container.Page(page =>
    {
        page.Header().Text("Page Header");
        page.Content().Text("Body content");
        page.Footer().AlignCenter().Text(text =>
        {
            text.CurrentPageNumber();
            text.Span(" / ");
            text.TotalPages();
        });
    });
}).GeneratePdf("output.pdf");
Enter fullscreen mode Exit fullscreen mode

After (IronPDF):

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

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align: center;'>Page Header</div>"
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align: center;'>Page {page} / {total-pages}</div>"
};

var pdf = renderer.RenderHtmlAsPdf("<p>Body content</p>");
pdf.SaveAs("output.pdf");
Enter fullscreen mode Exit fullscreen mode

IronPDF's headers/footers support full HTML/CSS styling.

Licensing Comparison

QuestPDF:

  • Free (MIT license) for non-commercial use or revenue < $2M
  • Commercial license required for companies with revenue > $2M

IronPDF:

  • Commercial license: $749 per developer
  • No revenue restrictions

If your company revenue > $2M, you'll need a commercial license for both libraries. IronPDF's $749 pricing is competitive.

Should You Migrate?

Migrate to IronPDF if:

  • You need HTML-to-PDF conversion (QuestPDF can't do this)
  • You use HTML templates, Razor views, or Blazor components
  • You need modern CSS/JavaScript support (Bootstrap, charts, etc.)
  • You need to manipulate existing PDFs (merge, split, extract, forms)

Stay with QuestPDF if:

  • You prefer code-first fluent API over HTML
  • Your PDFs are purely programmatic (no HTML templates)
  • You're building highly structured documents (invoices, certificates)
  • You're under $2M revenue (QuestPDF is free)

Hybrid approach if:

  • You need both code-first layouts (QuestPDF) AND HTML rendering (IronPDF)
  • You're generating complex multi-part documents
  • You want to leverage each library's strengths

Conclusion

QuestPDF and IronPDF solve different problems:

  • QuestPDF: Code-first, fluent API, programmatic layouts
  • IronPDF: HTML-to-PDF, Chromium rendering, web content

Most teams migrating from QuestPDF to IronPDF are doing so for HTML rendering capabilities. If that's your use case, IronPDF is the right choice.

If you need both approaches, use them together—QuestPDF for code-first layouts, IronPDF for HTML rendering and PDF manipulation.


Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.

Top comments (0)