Skip to footer content
MIGRATION GUIDES

How to Migrate from Scryber.Core to IronPDF in C#

Migrating from Scryber.Core to IronPDF moves your PDF generation workflow from a custom XHTML+CSS layout engine to a Chromium-based renderer with full CSS3 and JavaScript support. This guide provides a step-by-step migration path covering LGPL v3 licensing considerations, Scryber's XHTML-strict template model, and the rendering differences between the two engines.

Why Migrate from Scryber.Core to IronPDF

Understanding Scryber.Core

Scryber.Core (maintained by Richard Hewitson, current version 9.3.1) is an open-source library that parses XHTML+CSS templates with its own layout engine — not a browser. It supports CSS styling, Handlebars-style {{ }} data binding via doc.Params, and SVG, making it attractive for developers who want HTML-driven PDFs without a browser dependency.

Although Scryber.Core is a viable option for HTML-template-based PDF generation, several constraints drive teams to migrate.

Key Reasons to Migrate

  1. LGPL v3 License Concerns: Source-disclosure obligations apply if you modify Scryber itself; static linking in closed-source apps is permitted but the terms still constrain how you ship modifications.
  2. XHTML-strict Input: Templates must be valid XML — most real-world HTML needs cleanup before Scryber will parse it.
  3. Non-browser Renderer: A custom XHTML/CSS layout engine — modern CSS (Grid, full Flexbox, container queries) and any JavaScript are not executed.
  4. Smaller Community: Fewer worked examples than mainstream libraries.
  5. No JavaScript Execution: Static rendering only — charts, SPAs, and dynamic widgets must be pre-rendered.
  6. No Native URL-to-PDF: You must fetch HTML yourself (e.g., with HttpClient) and feed it in.
  7. Community-supported: Commercial support options are limited.

Scryber.Core vs IronPDF Comparison

Aspect Scryber.Core IronPDF
License LGPL v3 Commercial
Rendering Engine Custom XHTML/CSS layout engine Chromium
CSS Support Subset (no Grid, partial Flexbox) Full CSS3
JavaScript Not executed Full (Chromium V8)
Template Binding Handlebars-style {{ }} + <template> Standard (Razor, RazorLight, etc.)
Input Strictness Requires well-formed XHTML Accepts real-world HTML
Async Support PDFAsync MVC helper; sync core Full async API
Documentation Read-the-docs site + samples Extensive
Community Support Smaller Larger
Commercial Support Community-supported Commercial support available

IronPDF offers commercial support, documentation, and a larger user base compared to Scryber.Core. The library is licensed for commercial use without LGPL obligations.


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 Scryber.Core
dotnet remove package Scryber.Core

# Install IronPDF
dotnet add package IronPdf
# Remove Scryber.Core
dotnet remove package Scryber.Core

# Install IronPDF
dotnet add package IronPdf
SHELL

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"
$vbLabelText   $csharpLabel

Complete API Reference

Namespace Changes

// Before: Scryber.Core
using Scryber.Components;   // Document, Page, etc.
using Scryber.Drawing;      // Units, colours
using Scryber.PDF;          // RenderOptions / OutputCompressionType
using Scryber.Styles;       // Style elements (older XML template usage)

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
// Before: Scryber.Core
using Scryber.Components;   // Document, Page, etc.
using Scryber.Drawing;      // Units, colours
using Scryber.PDF;          // RenderOptions / OutputCompressionType
using Scryber.Styles;       // Style elements (older XML template usage)

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
Imports Scryber.Components   ' Document, Page, etc.
Imports Scryber.Drawing      ' Units, colours
Imports Scryber.PDF          ' RenderOptions / OutputCompressionType
Imports Scryber.Styles       ' Style elements (older XML template usage)

' After: IronPDF
Imports IronPdf
Imports IronPdf.Rendering
$vbLabelText   $csharpLabel

Core API Mappings

Scryber.Core IronPDF
Document.ParseDocument(reader, "", ParseSourceType.DynamicContent) renderer.RenderHtmlAsPdf(html)
Document.ParseDocument(path) renderer.RenderHtmlFileAsPdf(path)
doc.SaveAsPDF(path) pdf.SaveAs(path)
doc.SaveAsPDF(stream) pdf.BinaryData (byte[])
doc.Info.Title pdf.MetaData.Title
doc.Info.Author pdf.MetaData.Author
@page CSS in template renderer.RenderingOptions.PaperSize / margins
doc.RenderOptions renderer.RenderingOptions
Handlebars {{value}} + doc.Params Razor / string interpolation

Code Migration Examples

Example 1: Basic HTML to PDF Conversion

Before (Scryber.Core):

// NuGet: Install-Package Scryber.Core
using Scryber.Components;
using System.IO;

class Program
{
    static void Main()
    {
        // Scryber requires well-formed XHTML wrapped in an html root with the xhtml namespace
        string html = @"<html xmlns='http://www.w3.org/1999/xhtml'>
            <body><h1>Hello World</h1><p>This is a PDF document.</p></body>
        </html>";

        using (var reader = new StringReader(html))
        using (var doc = Document.ParseDocument(reader, string.Empty, ParseSourceType.DynamicContent))
        using (var stream = new FileStream("output.pdf", FileMode.Create))
        {
            doc.SaveAsPDF(stream);
        }
    }
}
// NuGet: Install-Package Scryber.Core
using Scryber.Components;
using System.IO;

class Program
{
    static void Main()
    {
        // Scryber requires well-formed XHTML wrapped in an html root with the xhtml namespace
        string html = @"<html xmlns='http://www.w3.org/1999/xhtml'>
            <body><h1>Hello World</h1><p>This is a PDF document.</p></body>
        </html>";

        using (var reader = new StringReader(html))
        using (var doc = Document.ParseDocument(reader, string.Empty, ParseSourceType.DynamicContent))
        using (var stream = new FileStream("output.pdf", FileMode.Create))
        {
            doc.SaveAsPDF(stream);
        }
    }
}
Imports Scryber.Components
Imports System.IO

Class Program
    Shared Sub Main()
        ' Scryber requires well-formed XHTML wrapped in an html root with the xhtml namespace
        Dim html As String = "<html xmlns='http://www.w3.org/1999/xhtml'>" &
                             "<body><h1>Hello World</h1><p>This is a PDF document.</p></body>" &
                             "</html>"

        Using reader As New StringReader(html),
              doc As Document = Document.ParseDocument(reader, String.Empty, ParseSourceType.DynamicContent),
              stream As New FileStream("output.pdf", FileMode.Create)
            doc.SaveAsPDF(stream)
        End Using
    End Sub
End Class
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

        var renderer = new ChromePdfRenderer();
        string html = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

        var renderer = new ChromePdfRenderer();
        string html = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf

Class Program
    Shared Sub Main()
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"

        Dim renderer = New ChromePdfRenderer()
        Dim html As String = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"

        Dim pdf = renderer.RenderHtmlAsPdf(html)
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Scryber.Core wraps the XHTML string in a StringReader, hands it to Document.ParseDocument with ParseSourceType.DynamicContent, and writes the PDF to a FileStream via SaveAsPDF. The XHTML namespace declaration is required — Scryber will reject HTML that is not well-formed XML.

IronPDF uses a ChromePdfRenderer instance with RenderHtmlAsPdf() to render HTML directly, and saves with SaveAs(). Real-world HTML5 is accepted as-is. See the HTML to PDF documentation for further examples.

Example 2: URL to PDF Conversion

Before (Scryber.Core):

// NuGet: Install-Package Scryber.Core
// Scryber has no native URL-to-PDF method — fetch the HTML yourself, then parse.
using Scryber.Components;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        string html = await client.GetStringAsync("https://www.example.com");

        // Most live HTML is not valid XHTML; expect to clean it
        // (e.g., HtmlAgilityPack) before Scryber will parse it.
        using (var reader = new StringReader(html))
        using (var doc = Document.ParseDocument(reader, string.Empty, ParseSourceType.DynamicContent))
        using (var stream = new FileStream("webpage.pdf", FileMode.Create))
        {
            doc.SaveAsPDF(stream);
        }
    }
}
// NuGet: Install-Package Scryber.Core
// Scryber has no native URL-to-PDF method — fetch the HTML yourself, then parse.
using Scryber.Components;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var client = new HttpClient();
        string html = await client.GetStringAsync("https://www.example.com");

        // Most live HTML is not valid XHTML; expect to clean it
        // (e.g., HtmlAgilityPack) before Scryber will parse it.
        using (var reader = new StringReader(html))
        using (var doc = Document.ParseDocument(reader, string.Empty, ParseSourceType.DynamicContent))
        using (var stream = new FileStream("webpage.pdf", FileMode.Create))
        {
            doc.SaveAsPDF(stream);
        }
    }
}
Imports Scryber.Components
Imports System.IO
Imports System.Net.Http
Imports System.Threading.Tasks

Module Program
    Async Function Main() As Task
        Using client As New HttpClient()
            Dim html As String = Await client.GetStringAsync("https://www.example.com")

            ' Most live HTML is not valid XHTML; expect to clean it
            ' (e.g., HtmlAgilityPack) before Scryber will parse it.
            Using reader As New StringReader(html)
                Using doc As Document = Document.ParseDocument(reader, String.Empty, ParseSourceType.DynamicContent)
                    Using stream As New FileStream("webpage.pdf", FileMode.Create)
                        doc.SaveAsPDF(stream)
                    End Using
                End Using
            End Using
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

        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()
    {
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf

Class Program
    Shared Sub Main()
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"

        Dim renderer As New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Scryber.Core has no native URL-to-PDF entry point. You fetch the HTML yourself with HttpClient.GetStringAsync() and feed it into Document.ParseDocument(). Because Scryber requires well-formed XHTML, most live pages will need cleanup (for example via HtmlAgilityPack) before they parse. JavaScript is not executed, so any dynamically-rendered content will be missing.

IronPDF's RenderUrlAsPdf() handles fetch, JavaScript execution, and CSS rendering in a single call via its Chromium engine. Learn more in our tutorials.

Example 3: Custom Page Settings and Margins

Before (Scryber.Core):

// NuGet: Install-Package Scryber.Core
// Page size and margins are normally declared in the XHTML/CSS template;
// the runtime RenderOptions object exposes output-side settings such as compression.
using Scryber.Components;
using Scryber.PDF;
using System.IO;

class Program
{
    static void Main()
    {
        // Page size and margins go in CSS @page; this is the Scryber idiom.
        string html = @"<html xmlns='http://www.w3.org/1999/xhtml'>
            <head>
                <style>
                    @page { size: A4 portrait; margin: 40pt; }
                </style>
            </head>
            <body><h1>Custom PDF</h1><p>With custom margins and settings.</p></body>
        </html>";

        using (var reader = new StringReader(html))
        using (var doc = Document.ParseDocument(reader, string.Empty, ParseSourceType.DynamicContent))
        using (var stream = new FileStream("custom.pdf", FileMode.Create))
        {
            // Output-side options (compression / conformance) are on RenderOptions.
            doc.RenderOptions.Compression = OutputCompressionType.FlateDecode;
            doc.SaveAsPDF(stream);
        }
    }
}
// NuGet: Install-Package Scryber.Core
// Page size and margins are normally declared in the XHTML/CSS template;
// the runtime RenderOptions object exposes output-side settings such as compression.
using Scryber.Components;
using Scryber.PDF;
using System.IO;

class Program
{
    static void Main()
    {
        // Page size and margins go in CSS @page; this is the Scryber idiom.
        string html = @"<html xmlns='http://www.w3.org/1999/xhtml'>
            <head>
                <style>
                    @page { size: A4 portrait; margin: 40pt; }
                </style>
            </head>
            <body><h1>Custom PDF</h1><p>With custom margins and settings.</p></body>
        </html>";

        using (var reader = new StringReader(html))
        using (var doc = Document.ParseDocument(reader, string.Empty, ParseSourceType.DynamicContent))
        using (var stream = new FileStream("custom.pdf", FileMode.Create))
        {
            // Output-side options (compression / conformance) are on RenderOptions.
            doc.RenderOptions.Compression = OutputCompressionType.FlateDecode;
            doc.SaveAsPDF(stream);
        }
    }
}
Imports Scryber.Components
Imports Scryber.PDF
Imports System.IO

Module Program

    Sub Main()
        ' Page size and margins go in CSS @page; this is the Scryber idiom.
        Dim html As String = "<html xmlns='http://www.w3.org/1999/xhtml'>" &
                             "<head>" &
                             "<style>" &
                             "@page { size: A4 portrait; margin: 40pt; }" &
                             "</style>" &
                             "</head>" &
                             "<body><h1>Custom PDF</h1><p>With custom margins and settings.</p></body>" &
                             "</html>"

        Using reader As New StringReader(html),
              doc As Document = Document.ParseDocument(reader, String.Empty, ParseSourceType.DynamicContent),
              stream As New FileStream("custom.pdf", FileMode.Create)

            ' Output-side options (compression / conformance) are on RenderOptions.
            doc.RenderOptions.Compression = OutputCompressionType.FlateDecode
            doc.SaveAsPDF(stream)
        End Using
    End Sub

End Module
$vbLabelText   $csharpLabel

After (IronPDF):

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

class Program
{
    static void Main()
    {
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 40;
        renderer.RenderingOptions.MarginBottom = 40;

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

class Program
{
    static void Main()
    {
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 40;
        renderer.RenderingOptions.MarginBottom = 40;

        string html = "<html><body><h1>Custom PDF</h1><p>With custom margins and settings.</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("custom.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Rendering

Class Program
    Shared Sub Main()
        IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"

        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
        renderer.RenderingOptions.MarginTop = 40
        renderer.RenderingOptions.MarginBottom = 40

        Dim html As String = "<html><body><h1>Custom PDF</h1><p>With custom margins and settings.</p></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)
        pdf.SaveAs("custom.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

In Scryber.Core, page size and margins are declared in the template via @page CSS, while doc.RenderOptions exposes output-side settings such as compression (OutputCompressionType.FlateDecode).

IronPDF moves page geometry to RenderingOptions on the renderer: PaperSize (set to PdfPaperSize.A4), MarginTop, and MarginBottom in millimeters. The page geometry lives on the API surface rather than inside the template.


Template Migration Patterns

Migrating Scryber Binding to Standard Templates

Scryber.Core uses XHTML with Handlebars-style {{ }} bindings (resolved via doc.Params) and a <template data-bind='...'> construct for repeating sections. To migrate, re-express these in standard .NET templating:

Scryber Binding (XHTML + Handlebars):

<p>{{model.Name}}</p>
<p>Total: {{model.Total}}</p>
<template data-bind='{{model.Items}}'>
    <p>{{.Name}}: {{.Price}}</p>
</template>
<p>{{model.Name}}</p>
<p>Total: {{model.Total}}</p>
<template data-bind='{{model.Items}}'>
    <p>{{.Name}}: {{.Price}}</p>
</template>
XML

IronPDF with C# String Interpolation:

var items = model.Items.Select(i => $"<li>{i.Name}: {i.Price:C}</li>");

var html = $@"
<p>{model.Name}</p>
<p>Total: {model.Total:C}</p>
<ul>
    {string.Join("", items)}
</ul>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
var items = model.Items.Select(i => $"<li>{i.Name}: {i.Price:C}</li>");

var html = $@"
<p>{model.Name}</p>
<p>Total: {model.Total:C}</p>
<ul>
    {string.Join("", items)}
</ul>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
Dim items = model.Items.Select(Function(i) $"<li>{i.Name}: {i.Price:C}</li>")

Dim html = $"
<p>{model.Name}</p>
<p>Total: {model.Total:C}</p>
<ul>
    {String.Join("", items)}
</ul>"

Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

Because IronPDF accepts plain HTML, you can use any .NET templating engine — Razor, RazorLight, Handlebars.Net — rather than Scryber's {{ }} + <template> constructs.


Headers and Footers Migration

Scryber.Core (XHTML + @page margin boxes):

<html xmlns='http://www.w3.org/1999/xhtml'>
    <head>
        <style>
            @page {
                @top-center { content: 'Company Report'; }
                @bottom-center { content: 'Page ' counter(page) ' of ' counter(pages); }
            }
        </style>
    </head>
    <body>
        <h1>Content Here</h1>
    </body>
</html>
<html xmlns='http://www.w3.org/1999/xhtml'>
    <head>
        <style>
            @page {
                @top-center { content: 'Company Report'; }
                @bottom-center { content: 'Page ' counter(page) ' of ' counter(pages); }
            }
        </style>
    </head>
    <body>
        <h1>Content Here</h1>
    </body>
</html>
HTML

IronPDF (HTML headers/footers):

using IronPdf;

var renderer = new ChromePdfRenderer();

// HTML header with full CSS support
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='width: 100%; text-align: center; font-size: 12pt; border-bottom: 1px solid #ccc;'>
            Company Report
        </div>",
    MaxHeight = 30
};

// HTML footer with page numbers
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='width: 100%; text-align: center; font-size: 10pt;'>
            Page {page} of {total-pages}
        </div>",
    MaxHeight = 25
};

var pdf = renderer.RenderHtmlAsPdf("<h1>Content Here</h1>");
pdf.SaveAs("report.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();

// HTML header with full CSS support
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='width: 100%; text-align: center; font-size: 12pt; border-bottom: 1px solid #ccc;'>
            Company Report
        </div>",
    MaxHeight = 30
};

// HTML footer with page numbers
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='width: 100%; text-align: center; font-size: 10pt;'>
            Page {page} of {total-pages}
        </div>",
    MaxHeight = 25
};

var pdf = renderer.RenderHtmlAsPdf("<h1>Content Here</h1>");
pdf.SaveAs("report.pdf");
Imports IronPdf

Dim renderer As New ChromePdfRenderer()

' HTML header with full CSS support
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
    .HtmlFragment = "
        <div style='width: 100%; text-align: center; font-size: 12pt; border-bottom: 1px solid #ccc;'>
            Company Report
        </div>",
    .MaxHeight = 30
}

' HTML footer with page numbers
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "
        <div style='width: 100%; text-align: center; font-size: 10pt;'>
            Page {page} of {total-pages}
        </div>",
    .MaxHeight = 25
}

Dim pdf = renderer.RenderHtmlAsPdf("<h1>Content Here</h1>")
pdf.SaveAs("report.pdf")
$vbLabelText   $csharpLabel

Scryber.Core defines headers and footers via @page margin boxes in CSS, using counter(page) and counter(pages) for page numbers. IronPDF uses HtmlHeaderFooter with full HTML/CSS for headers and footers and the placeholders {page} and {total-pages}.


New Capabilities After Migration

After migrating to IronPDF, you gain capabilities that Scryber.Core cannot provide:

PDF Merging

var pdf1 = PdfDocument.FromFile("chapter1.pdf");
var pdf2 = PdfDocument.FromFile("chapter2.pdf");
var pdf3 = PdfDocument.FromFile("chapter3.pdf");

var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("complete_book.pdf");
var pdf1 = PdfDocument.FromFile("chapter1.pdf");
var pdf2 = PdfDocument.FromFile("chapter2.pdf");
var pdf3 = PdfDocument.FromFile("chapter3.pdf");

var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("complete_book.pdf");
Dim pdf1 = PdfDocument.FromFile("chapter1.pdf")
Dim pdf2 = PdfDocument.FromFile("chapter2.pdf")
Dim pdf3 = PdfDocument.FromFile("chapter3.pdf")

Dim merged = PdfDocument.Merge(pdf1, pdf2, pdf3)
merged.SaveAs("complete_book.pdf")
$vbLabelText   $csharpLabel

Security and Metadata

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");

// Metadata
pdf.MetaData.Title = "My Document";
pdf.MetaData.Author = "John Doe";
pdf.MetaData.Subject = "Annual Report";
pdf.MetaData.Keywords = "report, annual, confidential";

// Security
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user456";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;

pdf.SaveAs("protected.pdf");
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");

// Metadata
pdf.MetaData.Title = "My Document";
pdf.MetaData.Author = "John Doe";
pdf.MetaData.Subject = "Annual Report";
pdf.MetaData.Keywords = "report, annual, confidential";

// Security
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user456";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;

pdf.SaveAs("protected.pdf");
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>")

' Metadata
pdf.MetaData.Title = "My Document"
pdf.MetaData.Author = "John Doe"
pdf.MetaData.Subject = "Annual Report"
pdf.MetaData.Keywords = "report, annual, confidential"

' Security
pdf.SecuritySettings.OwnerPassword = "owner123"
pdf.SecuritySettings.UserPassword = "user456"
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights

pdf.SaveAs("protected.pdf")
$vbLabelText   $csharpLabel

Feature Comparison Summary

Feature Scryber.Core IronPDF
HTML to PDF XHTML+CSS via custom layout engine Full Chromium
URL to PDF Manual fetch only Native RenderUrlAsPdf
CSS Grid Not supported Full support
Flexbox Partial Full support
JavaScript Not executed Full (V8)
Data Binding {{ }} Handlebars + doc.Params Razor / RazorLight / interpolation
Headers/Footers @page margin boxes / template sections HtmlHeaderFooter with {page} {total-pages}
Merge PDFs Not supported Built-in PdfDocument.Merge
Split PDFs Not supported Yes
Watermarks Via overlay HTML in template Native ApplyStamp / ApplyWatermark
Digital Signatures Not supported Yes
PDF/A Not supported Yes (PDF/A-1b, PDF/A-3)
Password Protection Not supported Full (user/owner + permissions)
Async Support PDFAsync MVC helper; sync core Full async surface
Cross-Platform Yes (.NET Std 2.0/2.1, .NET 8/9/10) Yes

Migration Checklist

Pre-Migration

  • Audit all Scryber templates for XHTML/binding patterns
  • Document data binding patterns used ({{model.Property}})
  • Identify custom styles that need CSS conversion
  • Obtain IronPDF license key from ironpdf.com

Code Updates

  • Remove Scryber.Core NuGet package
  • Install IronPdf NuGet package
  • Update namespace imports (using Scryber.Components; / Scryber.Drawing; / Scryber.PDF;using IronPdf;)
  • Replace Document.ParseDocument(reader, "", ParseSourceType.DynamicContent) with renderer.RenderHtmlAsPdf(html)
  • Replace doc.SaveAsPDF(stream) with pdf.SaveAs(path) or pdf.BinaryData
  • Convert XHTML templates to plain HTML5 (no namespace requirement)
  • Replace {{ }} Handlebars binding with standard templating (Razor / string interpolation)
  • Move @page CSS to renderer.RenderingOptions (PaperSize, MarginTop, etc.)
  • Convert @page margin-box headers/footers to HtmlHeaderFooter with {page} and {total-pages} placeholders
  • Add license initialization at application startup

Testing

  • Test all document templates
  • Verify styling matches (leverage full CSS support)
  • Test data binding with new templating
  • Verify page breaks
  • Test headers/footers with page number placeholders
  • Performance comparison

Please noteScryber is a registered trademark of its respective owner. This site is not affiliated with, endorsed by, or sponsored by PerceiveIT Limited. 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

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me