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 critical unpatched security vulnerabilities from wkhtmltopdf:
- CVE-2022-35583 (SSRF): Server-Side Request Forgery allowing attackers to access internal network resources
- Abandoned Project: wkhtmltopdf has been unmaintained since 2020
- No Security Patches: Known vulnerabilities will never be fixed
Technical Problems
| Issue | Impact |
|---|---|
| Thread Safety | SynchronizedConverter still crashes in production under concurrent load |
| Native Binaries | Complex deployment with platform-specific libwkhtmltox binaries |
| CSS Limitations | No Flexbox, Grid, or modern CSS support |
| JavaScript | Inconsistent execution, timeouts |
| Rendering | Outdated WebKit engine (circa 2015) |
| Maintenance | Last update: 2018 |
Architecture Comparison
| Aspect | DinkToPdf | IronPDF |
|---|---|---|
| Security | CVE-2022-35583 (SSRF), unpatched | No known vulnerabilities |
| Rendering Engine | Outdated WebKit (2015) | Modern Chromium |
| Thread Safety | Crashes in concurrent use | Fully thread-safe |
| Native Dependencies | Platform-specific binaries | Pure NuGet package |
| CSS Support | No Flexbox/Grid | Full CSS3 |
| JavaScript | Limited, inconsistent | Full support |
| Maintenance | Abandoned (2018) | 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+ or .NET Core 3.1 / .NET 5-9
- 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 | SynchronizedConverter required | 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 IronPdfStep 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;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";Complete API Migration Reference
Core Class Mapping
| DinkToPdf | IronPDF | Notes |
|---|---|---|
SynchronizedConverter | ChromePdfRenderer | Thread-safe by default |
BasicConverter | ChromePdfRenderer | Same class, simpler |
PdfTools | Not needed | Internalized |
HtmlToPdfDocument | Not needed | Direct method calls |
GlobalSettings | RenderingOptions | Part of renderer |
ObjectSettings | RenderingOptions | Part of renderer |
MarginSettings | Individual margin properties | MarginTop, MarginBottom, etc. |
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);
}
}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");
}
}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);
}
}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");
}
}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);
}
}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");
}
}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/nullNo Singleton Required
DinkToPdf's SynchronizedConverter had to be registered as a singleton to avoid crashes. IronPDF's ChromePdfRenderer is thread-safe with any DI lifetime:
// DinkToPdf - MUST be 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 - MUST be 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 (these crashed with DinkToPdf)
- 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
Future-Proofing Your PDF Infrastructure
With .NET 10 on the horizon and C# 14 introducing new language features, choosing a PDF library that's actively maintained ensures long-term compatibility. IronPDF's modern Chromium engine receives regular updates, while DinkToPdf's abandoned wkhtmltopdf remains frozen at 2015 capabilities—a growing gap that will only widen as web standards evolve through 2025 and 2026.
Additional Resources
Migrating from DinkToPdf to IronPDF eliminates critical security vulnerabilities (CVE-2022-35583), thread safety crashes, native binary deployment complexity, and outdated CSS rendering. The transition to a modern Chromium engine delivers full CSS3 support, reliable JavaScript execution, and the peace of mind that comes with an actively maintained library.






