wkhtmltopdf alternative for C#
In C#, the archive arrives with a crash attached: DinkToPdf P/Invokes the native library, and the native interop is the part that breaks under concurrent conversion. Playwright for .NET replaces both: page.PdfAsync() prints in a real Chromium, with modern CSS applied and web fonts loaded from the page, and each render runs in an isolated context instead of behind SynchronizedConverter.
DinkToPdf and TuesPechkin wrap the native binary and crash under concurrency: both P/Invoke the archived wkhtmltopdf library, so the frozen engine and the thread-unsafe native layer arrive together.
Install
dotnet add package Microsoft.Playwright, then playwright install to fetch the browsers into the project's cache, so the render engine's version travels with the app, not the machine.
What you keep: DinkToPdf settings become PdfOptions
The DinkToPdf settings carry over under new names. Paper size becomes Format = "A4", orientation becomes Landscape = true, margins become the Margin object, and PrintBackground = true keeps backgrounds; the hub's flag map names the browser equivalent for the rest.
What actually changes
DinkToPdf P/Invokes the native wkhtmltopdf library, so the freeze arrived twice: the engine stopped moving, and the native interop that loads it is the part that crashes under concurrent conversion, which is why SynchronizedConverter exists at all. Playwright for .NET owns the browser process, hands each render an isolated context, and the serialization guard is guarding a library that is no longer there.
Before and after on a typical DinkToPdf call:
Before, DinkToPdf P/Invoking the archived native library:
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = { PaperSize = PaperKind.A4 },
Objects = { new ObjectSettings { HtmlContent = html,
WebSettings = new WebSettings { PrintBackground = true } } },
};
byte[] pdf = converter.Convert(doc);
After, Playwright for .NET printing with Chromium:
using Microsoft.Playwright;
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewPageAsync();
await page.GotoAsync("https://example.com/report",
new PageGotoOptions { WaitUntil = WaitUntilState.NetworkIdle });
await page.PdfAsync(new PagePdfOptions
{ Path = "out.pdf", Format = "A4", PrintBackground = true });
Two properties carry the repair: WaitUntil = WaitUntilState.NetworkIdle waits for the page to finish before printing, and PrintBackground = true keeps background colors and images. Each render runs in an isolated browser context, so the concurrent-conversion crashes leave with the P/Invoke.
Verify before you cut over
Point the after snippet at your worst legacy template while the old converter still runs, and put the two outputs side by side: page count, fonts, backgrounds, page breaks. Most differences are the workarounds you no longer port; the remainder are layout changes that deserve a look before cutover.
Print-CSS engine or browser?
print-CSS engines stay correct for authored documents only. Prince and WeasyPrint lay out CSS documents written for print, but neither runs the page's JavaScript, so a client-rendered page never arrives intact; those pages must use Chromium.
Frequently asked questions
Is DinkToPdf maintained?
No: it P/Invokes the native wkhtmltopdf library, which was archived in 2023, and the native interop is the layer that crashes under concurrent conversions, which is why SynchronizedConverter serializes every call.
Does Playwright for .NET need anything installed?
The browsers: dotnet add package Microsoft.Playwright, then playwright install fetches Chromium into the project's cache, so the render engine's version travels with the app, not the machine.
Method
Checked 2026-09-11 against the DinkToPdf settings reference and the current Playwright for .NET PDF documentation.
More languages: the Python migration guide, the PHP migration guide, the Java migration guide, the Go migration guide. The wkhtmltopdf alternatives hub holds the full flag table and the honest before-and-after notes.
Going deeper: the formatting guide walks the breakages the old engine caused and the settings that fix them, the open-source comparison prices free routes against hosted, and the webcapture product page keeps engine, pricing, and quick start together.
Render your first page in seconds
Mint a key, POST a URL, and the finished document comes back in the same response; pass ?wait=false for a job ticket with poll and download URLs. The first 50 renders a month are free, and there is no credit card. Not ready for a key? The free URL to PDF tool renders public pages without one.