Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For most .NET Core applications, the practical free choices are SelectPdf Community Edition, DinkToPdf with wkhtmltopdf, and PuppeteerSharp. SelectPdf is the easiest documented package when every document fits within five pages. DinkToPdf is an MIT-licensed .NET wrapper around the native wkhtmltopdf WebKit engine, so you must ship the correct binary. PuppeteerSharp is MIT-licensed and drives headless Chromium, giving you the most browser-like CSS and JavaScript behavior at the cost of browser deployment and startup management.

There is no neutral benchmark establishing one universal winner. Test your own templates, fonts, external assets, JavaScript timing and container image before committing to production.

Which free library should you choose?

Library Rendering engine Free-use condition Deployment burden Best fit
SelectPdf Community Edition Vendor engine advertising HTML5, CSS3 and JavaScript support Five pages maximum per generated PDF Packaged .NET converter Short invoices, certificates and reports where the page cap is acceptable
DinkToPdf plus wkhtmltopdf Qt WebKit Open-source components; no stated page cap Native wkhtmltopdf binary for each operating system and CPU architecture Teams comfortable managing native files and older WebKit behavior
PuppeteerSharp Headless Chromium MIT-licensed .NET port; no stated page cap Chromium acquisition, executable permissions and process resources Modern CSS, JavaScript-heavy pages and browser-faithful output

Choose the renderer, not just the NuGet package. A wrapper’s license does not remove the license and operational requirements of its native or browser engine.

SelectPdf Community Edition

SelectPdf describes its Community Edition as free for any use, including production, and lists support for .NET Framework, .NET Core and .NET 5 through .NET 10. It accepts a URL, an HTML file or a raw HTML string and advertises HTML5, CSS3, JavaScript, custom headers and footers. The decisive restriction is a maximum of five PDF pages per document.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When it is the right choice

  • Your output is guaranteed to stay at five pages or fewer.
  • You want the smallest amount of rendering infrastructure in an ASP.NET Core service.
  • You need a conventional .NET API rather than a browser automation workflow.

Basic C# example

Install the Community Edition package documented by SelectPdf, then convert a string:

using SelectPdf;

var html = "<html><body><h1>Invoice</h1><p>Paid in full</p></body></html>";
var converter = new HtmlToPdf();
converter.Options.MarginTop = 20;
converter.Options.MarginBottom = 20;
converter.Options.DisplayHeader = true;
converter.Header.DisplayOnFirstPage = true;
converter.Header.Height = 30;
converter.Header.Add("Generated report", 10, 10, 0);

PdfDocument document = converter.ConvertHtmlString(html);
document.Save("invoice.pdf");
document.Close();

For a URL, use the corresponding URL conversion method from the package and make sure the rendering host can reach every stylesheet, image and font. Keep the five-page limit visible in validation code; otherwise a template change can turn a previously valid document into a production failure or truncation.

When to move to the commercial package

SelectPdf documents a commercial package for documents over five pages and for features such as PDF editing, PDF-to-text or image operations, forms, portfolios, PDF/UA and PDF/A. Treat those as separate licensing and capability decisions rather than assuming the Community Edition includes them.

DinkToPdf with wkhtmltopdf

DinkToPdf is an MIT-licensed .NET Core P/Invoke wrapper for wkhtmltopdf. wkhtmltopdf is an open-source LGPLv3 command-line tool that renders through Qt WebKit. The wrapper is not a self-contained renderer: the native wkhtmltopdf library must be copied beside your application for the target operating system and CPU architecture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install and package the native binary

  1. Add the DinkToPdf NuGet package.
  2. Obtain a wkhtmltopdf build compatible with your operating system and architecture.
  3. Copy the native library into the published application’s expected location and include it in your container or deployment artifact.
  4. Verify execution in the same identity used by the web process; a local developer installation does not prove that a Linux container or Windows service can load it.

ASP.NET Core registration

DinkToPdf documents BasicConverter for single-threaded applications and SynchronizedConverter for multithreaded applications and web servers. Register the converter as a singleton so native resources are not repeatedly initialized:

using DinkToPdf;
using DinkToPdf.Contracts;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<IConverter>(new SynchronizedConverter(new PdfTools()));
var app = builder.Build();

app.MapGet("/invoice.pdf", (IConverter converter) =>
{
    var document = new HtmlToPdfDocument
    {
        GlobalSettings =
        {
            ColorMode = ColorMode.Color,
            Orientation = Orientation.Portrait,
            PaperSize = PaperKind.A4,
            Margins = new MarginSettings { Top = 12, Bottom = 12, Left = 12, Right = 12 }
        },
        Objects =
        {
            new ObjectSettings
            {
                HtmlContent = "<h1>Invoice</h1><p>Example</p>",
                WebSettings = { DefaultEncoding = "utf-8" }
            }
        }
    };

    byte[] pdf = converter.Convert(document);
    return Results.File(pdf, "application/pdf", "invoice.pdf");
});

app.Run();

WebKit compatibility trade-off

WebKit is not Chromium. Modern layout features, newer JavaScript APIs, web fonts and complex client-side applications can render differently from the same page in a current browser. Pin the wkhtmltopdf build, keep the binary with your deployment manifest and test pages that use flexbox, grid, cross-origin assets and delayed JavaScript.

PuppeteerSharp with headless Chromium

PuppeteerSharp is a .NET port of the official Node.js Puppeteer API. Its documentation lists a .NET Standard 2.0 build for .NET Framework 4.6.1 and .NET Core 2.0 or greater, plus a .NET 8 build, under an MIT license. It controls Chromium, so it is generally the closest of these options to what a user sees in a current browser.

Download a browser and generate a PDF

using PuppeteerSharp;

await new BrowserFetcher().DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
    Headless = true,
    Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" }
});

await using var page = await browser.NewPageAsync();
await page.SetContentAsync("<html><body><h1>Report</h1><p>Ready</p></body></html>", new NavigationOptions
{
    WaitUntil = new[] { WaitUntilNavigation.Networkidle0 }
});
await page.EvaluateExpressionAsync("document.fonts.ready");
await page.PdfAsync("report.pdf", new PdfOptions
{
    Format = PaperFormat.A4,
    PrintBackground = true,
    MarginOptions = new MarginOptions { Top = "12mm", Bottom = "12mm", Left = "12mm", Right = "12mm" }
});

For a remote page, call GoToAsync with an appropriate wait condition instead of SetContentAsync. In a restricted container, Chromium may need additional system libraries and writable cache or temporary directories. The --no-sandbox switch has security implications; use a sandboxed configuration when your hosting environment supports it rather than copying this flag blindly.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Control timing and assets

  • Wait for a specific application-ready selector when the page performs asynchronous rendering.
  • Use document.fonts.ready before printing when typography matters.
  • Prefer absolute, reachable asset URLs or embed critical CSS and images.
  • Reuse a browser process where safe, but isolate pages and close them after each job to avoid memory growth.

Rendering, deployment and licensing decisions

CSS and JavaScript fidelity

SelectPdf advertises HTML5, CSS3 and a JavaScript runtime. DinkToPdf uses Qt WebKit and therefore follows a different, older browser compatibility path. PuppeteerSharp uses Chromium and is the strongest candidate for applications whose output depends on current browser APIs. None of those descriptions replaces testing your actual templates.

Native versus browser dependencies

DinkToPdf requires a native library matched to the target OS and CPU. PuppeteerSharp requires downloading or provisioning Chromium and meeting its runtime library requirements. SelectPdf’s Community Edition is the most packaged approach, but its five-page ceiling is a hard product constraint.

Concurrency

For ASP.NET Core, use DinkToPdf’s synchronized converter as documented and register it as a singleton. For PuppeteerSharp, limit simultaneous pages or browser processes with an application queue; PDF generation is resource-intensive even when requests are short. Measure memory, CPU and queue latency in the same container image used in production.

License review

Check the MIT terms for DinkToPdf and PuppeteerSharp, the LGPLv3 terms for the wkhtmltopdf component, and SelectPdf’s Community Edition terms before distributing a product. IronPDF is a commercial alternative; its documentation discusses inclusion of wkhtmltopdf LGPL code, so verify current licensing and pricing directly if you evaluate it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Production validation checklist

  1. Render representative short and long documents, including the maximum expected page count.
  2. Test local fonts, web fonts, right-to-left text, Unicode symbols, images, SVG and large tables.
  3. Exercise delayed JavaScript, authenticated assets, redirects, broken URLs and slow third-party resources.
  4. Run the same tests in the published operating-system image, not only on a developer workstation.
  5. Compare page breaks, headers, footers, links, metadata and file size against an approved fixture.
  6. Set request and rendering timeouts, cancel abandoned jobs and log the renderer version with every failure.
  7. Load-test with realistic concurrency and watch memory for browser or native-process leaks.

No neutral source establishes a universal speed or accuracy winner, so a small fixture suite is more useful than an internet ranking.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

“Library cannot be loaded” with DinkToPdf

The native wkhtmltopdf file is missing, in the wrong directory or built for a different architecture. Copy the correct binary into the published output, verify its name and dependencies, and test inside the deployment container.

Blank or incomplete output

Usually the renderer captured the page before JavaScript finished, could not reach an asset, or followed an authentication redirect. Add an explicit readiness wait, make assets reachable from the renderer, and log the final response URL and console errors.

Fonts or symbols differ

Install the required fonts in the runtime image or embed them, wait for font loading in Chromium, and verify that the selected renderer supports the font format. A browser on your workstation does not share fonts with a minimal container.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Unexpected page breaks

Define paper size, margins and print styles explicitly. Exercise long table rows and images, and keep a golden PDF or text extraction check in CI so template changes are detected.

Chromium fails to start

Provision the browser revision and its shared libraries, ensure the process user can access the cache and temporary directories, and inspect sandbox permissions. Avoid disabling the sandbox unless your isolation model explicitly requires it.

Or skip the browser setup

If your requirement is simply to turn a reachable website URL into a PDF or image, ScreenshotNeo provides a hosted endpoint instead of making your .NET service package wkhtmltopdf or Chromium. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; those cleanup steps can be disabled individually. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

See the ScreenshotNeo API documentation for current parameters. The same endpoint can return PNG, JPEG, WebP or PDF:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo’s Free plan includes 1,000 shots per month with no card. Paid plans are Starter $5 for 3,000 shots, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000 and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account to try it without a card.

Frequently Asked Questions

Can SelectPdf Community Edition create a 20-page report?

Not under its documented Community Edition limit: each generated PDF is capped at five pages. Use another renderer or evaluate SelectPdf’s commercial package for longer documents.

Does DinkToPdf include wkhtmltopdf automatically?

No. DinkToPdf is the .NET wrapper; the native wkhtmltopdf library must be supplied for the target operating system and CPU architecture.

Which option behaves most like Chrome?

PuppeteerSharp, because it drives headless Chromium. It still requires browser provisioning and should be validated in the same runtime image you deploy.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.