How to Migrate from DinkToPdf to IronPDF in C#
DinkToPdf wraps wkhtmltopdf, inheriting all its security vulnerabilities and technical limitations. Understanding these issues is critical for evaluating migration urgency.
Critical Security Issues
DinkToPdf inherits unpatched security advisories from wkhtmltopdf:
- CVE-2022-35583 (SSRF): A Server-Side Request Forgery advisory against wkhtmltopdf 0.12.6 (CVSS 9.8 in NVD; disputed by the upstream project as an application-side input-sanitization issue rather than a library bug). Either way, it will not be patched.
- Archived Project: The
wkhtmltopdf/wkhtmltopdfrepository was archived on January 2, 2023, and the entirewkhtmltopdfGitHub organization was archived on July 10, 2024. - No Future Security Patches: Any known or future vulnerabilities will not be fixed upstream.
Technical Problems
| Issue | Impact |
|---|---|
| Thread Safety | BasicConverter is single-threaded only; SynchronizedConverter serializes calls and can still hit native-side crashes under load |
| Native Binaries | Complex deployment with platform-specific libwkhtmltox binaries |
| CSS Limitations | Older QtWebKit fork — no modern Flexbox/Grid layout support |
| JavaScript | Inconsistent execution, timeouts |
| Rendering | Outdated QtWebKit-based engine (wkhtmltopdf 0.12.6, last release June 2020) |
| Maintenance | DinkToPdf 1.0.8 last released April 18, 2017 on NuGet |
Architecture Comparison
| Aspect | DinkToPdf | IronPDF |
|---|---|---|
| Security | CVE-2022-35583 (SSRF), unpatched / disputed upstream | No known critical CVEs |
| Rendering Engine | Older QtWebKit fork (wkhtmltopdf 0.12.6) | Modern Chromium |
| Thread Safety | SynchronizedConverter serializes calls; native-side crashes reported under load |
Thread-safe by design |
| Native Dependencies | Platform-specific libwkhtmltox binaries |
Managed NuGet package |
| CSS Support | No modern Flexbox/Grid | Full CSS3 |
| JavaScript | Limited, inconsistent | Supported |
| Maintenance | DinkToPdf last release April 2017; wkhtmltopdf org archived July 2024 | Actively maintained |
Feature Comparison
| Feature | DinkToPdf | IronPDF |
|---|---|---|
| HTML to PDF | ✅ (outdated engine) | ✅ (Chromium) |
| URL to PDF | ✅ | ✅ |
| Custom margins | ✅ | ✅ |
| Headers/Footers | ✅ (limited) | ✅ (full HTML) |
| CSS3 | ❌ Limited | ✅ Full |
| Flexbox/Grid | ❌ | ✅ |
| JavaScript | ⚠ Limited | ✅ Full |
| PDF manipulation | ❌ | ✅ |
| Form filling | ❌ | ✅ |
| Digital signatures | ❌ | ✅ |
| Encryption | ❌ | ✅ |
| Watermarks | ❌ | ✅ |
| Merge/Split | ❌ | ✅ |
Pre-Migration Preparation
Prerequisites
Ensure your environment meets these requirements:
- .NET Framework 4.6.2+, .NET Core 3.1+, or .NET 5/6/7/8/9/10
- Visual Studio 2019+ or VS Code with C# extension
- NuGet Package Manager access
- IronPDF license key (free trial available at ironpdf.com)
Audit DinkToPdf Usage
Run these commands in your solution directory to identify all DinkToPdf references:
# Find all DinkToPdf usages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .
# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .
# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
# Find all DinkToPdf usages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .
# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .
# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
Breaking Changes to Anticipate
| Change | DinkToPdf | IronPDF | Impact |
|---|---|---|---|
| Converter | SynchronizedConverter(new PdfTools()) |
ChromePdfRenderer |
Simpler instantiation |
| Document | HtmlToPdfDocument |
Direct method call | No document object |
| Settings | GlobalSettings + ObjectSettings |
RenderingOptions |
Single options object |
| Return type | byte[] |
PdfDocument |
More powerful object |
| Binary | libwkhtmltox.dll/so |
None (managed) | Remove native files |
| Thread safety | BasicConverter single-threaded; SynchronizedConverter serializes |
Thread-safe by default | Simpler code |
| DI | Singleton required | Any lifetime | Flexible |
Step-by-Step Migration Process
Step 1: Update NuGet Packages
Remove DinkToPdf and install IronPDF:
# Remove DinkToPdf
dotnet remove package DinkToPdf
# Install IronPDF
dotnet add package IronPdf
# Remove DinkToPdf
dotnet remove package DinkToPdf
# Install IronPDF
dotnet add package IronPdf
Step 2: Remove Native Binaries
Delete these platform-specific files from your project:
libwkhtmltox.dll(Windows)libwkhtmltox.so(Linux)libwkhtmltox.dylib(macOS)
IronPDF has no native dependencies—everything is managed code.
Step 3: Update Namespace References
Replace DinkToPdf namespaces with IronPDF:
// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;
// Add this
using IronPdf;
// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;
// Add this
using IronPdf;
Imports IronPdf
Step 4: Configure License
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Complete API Migration Reference
Core Class Mapping
| DinkToPdf | IronPDF |
|---|---|
SynchronizedConverter |
ChromePdfRenderer |
BasicConverter |
ChromePdfRenderer |
PdfTools |
Not needed |
HtmlToPdfDocument |
Not needed |
GlobalSettings |
RenderingOptions |
ObjectSettings |
RenderingOptions |
MarginSettings |
Individual margin properties |
GlobalSettings Mapping
| DinkToPdf GlobalSettings | IronPDF Equivalent |
|---|---|
ColorMode = ColorMode.Color |
Default (always color) |
Orientation = Orientation.Portrait |
PaperOrientation = PdfPaperOrientation.Portrait |
Orientation = Orientation.Landscape |
PaperOrientation = PdfPaperOrientation.Landscape |
PaperSize = PaperKind.A4 |
PaperSize = PdfPaperSize.A4 |
Margins = new MarginSettings() |
Individual margin properties |
MarginSettings Mapping
| DinkToPdf Margins | IronPDF Equivalent |
|---|---|
Margins.Top = 10 |
MarginTop = 10 |
Margins.Bottom = 10 |
MarginBottom = 10 |
Margins.Left = 15 |
MarginLeft = 15 |
Margins.Right = 15 |
MarginRight = 15 |
Code Migration Examples
Basic HTML to PDF
The fundamental conversion demonstrates the dramatic simplification from DinkToPdf's verbose configuration to IronPDF's streamlined API.
DinkToPdf Implementation:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = {
New ObjectSettings() With {
.HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
.WebSettings = New WebSettings() With {
.DefaultEncoding = "utf-8"
}
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
End Sub
End Module
IronPDF Implementation:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDF reduces a 20-line DinkToPdf configuration to 4 lines. No SynchronizedConverter, no PdfTools, no HtmlToPdfDocument, no ObjectSettings—just render and save. For more options, see the HTML to PDF documentation.
URL to PDF Conversion
DinkToPdf Implementation:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
Page = "https://www.example.com",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
Page = "https://www.example.com",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = New List(Of ObjectSettings) From {
New ObjectSettings() With {
.Page = "https://www.example.com"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("webpage.pdf", pdf)
End Sub
End Module
IronPDF Implementation:
// 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("webpage.pdf");
}
}
// 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("webpage.pdf");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
IronPDF's RenderUrlAsPdf replaces the nested ObjectSettings.Page configuration with a direct method call. For more options, see the URL to PDF documentation.
Custom Settings with Landscape and Margins
DinkToPdf Implementation:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("custom.pdf", pdf);
}
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("custom.pdf", pdf);
}
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Landscape,
.PaperSize = PaperKind.A4,
.Margins = New MarginSettings() With {
.Top = 10,
.Bottom = 10,
.Left = 15,
.Right = 15
}
},
.Objects = {
New ObjectSettings() With {
.HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
.WebSettings = New WebSettings() With {
.DefaultEncoding = "utf-8"
}
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("custom.pdf", pdf)
End Sub
End Module
IronPDF Implementation:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 15;
renderer.RenderingOptions.MarginRight = 15;
var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
pdf.SaveAs("custom.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 15;
renderer.RenderingOptions.MarginRight = 15;
var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
pdf.SaveAs("custom.pdf");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 15
renderer.RenderingOptions.MarginRight = 15
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>")
pdf.SaveAs("custom.pdf")
End Sub
End Module
IronPDF's RenderingOptions replaces both GlobalSettings and MarginSettings with a unified, fluent API. For more configuration options, see the rendering options documentation.
Critical Migration Notes
Remove Native Binaries
The most important cleanup step is removing wkhtmltopdf native binaries. IronPDF has no native dependencies:
# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
No Singleton Required
DinkToPdf's documented guidance is to register SynchronizedConverter as a singleton. IronPDF's ChromePdfRenderer is thread-safe with any DI lifetime:
// DinkToPdf - typically registered as singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
// IronPDF - any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
// DinkToPdf - typically registered as singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
// IronPDF - any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
Richer Return Type
DinkToPdf returns byte[]. IronPDF returns PdfDocument with manipulation capabilities:
// DinkToPdf returns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");
// IronPDF returns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
// DinkToPdf returns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");
// IronPDF returns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
Full CSS3 Support
Modern layouts that fail in DinkToPdf work perfectly in IronPDF:
// DinkToPdf - doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>"; // Broken!
// IronPDF - full support (modern Chromium)
var html = @"
<div style='display: flex; justify-content: space-between;'>
<div>Left</div>
<div>Right</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html); // Works!
// DinkToPdf - doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>"; // Broken!
// IronPDF - full support (modern Chromium)
var html = @"
<div style='display: flex; justify-content: space-between;'>
<div>Left</div>
<div>Right</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html); // Works!
Post-Migration Checklist
After completing the code migration, verify the following:
- Run all unit tests to verify PDF generation works correctly
- Test multi-threaded scenarios (the
SynchronizedConverterpath serializes calls and was prone to native-side crashes under load) - Compare PDF output quality (IronPDF's Chromium renders better)
- Verify CSS rendering (Flexbox/Grid now works)
- Test JavaScript execution (reliable with IronPDF)
- Update CI/CD pipelines to remove wkhtmltopdf installation
- Verify security scan passes (no more CVE-2022-35583 flags)
- Remove native binary deployment from Docker/deployment scripts
Additional Resources
Migrating from DinkToPdf to IronPDF retires the unpatched wkhtmltopdf attack surface (CVE-2022-35583), the serialized SynchronizedConverter concurrency model, native binary deployment, and the older QtWebKit rendering path. The transition to a modern Chromium engine delivers full CSS3 support, reliable JavaScript execution, and an actively maintained library.

