From my experience, every product will eventually want to export some messages or generate a report and it obviously needs to be a PDF. Primarily working with C# these days, it’s a recurring quest to find a good PDF rendering solution for .NET.
Quest Unlocked!
Naturally, I first started looking for permissively licensed libraries, which could be used free of charge and without additional license requirements. This means anything with a copyleft or commercial license is out of the race. Financial support for open source project or commercialization of said projects is currently a hot topic and not something I want to delve deeper into in this post. Some of my views can be found in other blog posts (here, here, or here).
Additionally, I really don’t want to ship a browser engine such as Chromium or WebKit, “just” to render a PDF. It reminds me of the saying: “If all you have is a hammer, everything looks like a nail.” However, while looking at existing solutions, I realized that the hard part is not writing the PDF file format, but it’s the layouting, positioning, styling, etc. that is complicated. It’s also the reason why many solutions do go with a browser engine, because layouting, positioning, styling, etc. is what the browser engines are really good at.
This opened up new search criteria in the quest to find a PDF rendering solution:
- A library that can represent a DOM (Document Object Model)
- A library that can layout and style a document
- A library that can write the PDF format
- A library that can translate between the DOM and PDF format
- A library that can translate between some document format and the library specific DOM
The question no longer is “How do I render a PDF?”, but turned into “How do I get this format I have, into a DOM format a library expects for layouting and styling?” and “How do I get that DOM into a PDF?”
Understanding the problem more, my refined search turned up multiple permissively licensed libraries that can write PDFs, but only really one permissively licensed library that does layouting and styling.
Side Quest: QuestPDF
QuestPDF is a modern, well maintained, open source project, that can be freely used for non-commercial projects, non-profits, or companies with a revenue that is less than $2M. Everyone else needs to purchase a commercial license. This is a fairly common way to try and build a self-sustaining open source project.
What’s special about QuestPDF is, that the code for their “free version” is licensed under the MIT license. So while the project license makes a distinction between free and commercial, the code itself ends up being licensed under MIT, which explicitly allows the redistribution. In theory this means, that as a private person, one could republish QuestPDF fully under MIT, so that as commercial entity, one is no longer constraint by the dual license.
It’s an odd licensing choice, given that most projects in similar situations would come up with their own license terms for both free and commercial uses. I assume QuestPDF considered that few companies would want to take this legally uncertain route and either decide to pay or steer clear of QuestPDF.
Here Be Dragons!
Now follows a pretty exhaustive list of libraries that are somehow related to the PDF creation process and that I had a brief look at. If you know of additional candidates, please leave a comment or reach out, I’m eager to try them and update the list.
- MigraDoc is a document generator. It supports almost anything you find in any good word processor. You just add paragraphs, tables, charts, arrange all this in sections, use bookmarks to create links, tables of contents, indexes, etc. MigraDoc will do the layout, creating page breaks as needed. MigraDoc will create PDF or RTF documents.
- LiteHtmlSharp is a C# cross-platform library for HTML/CSS(2/3) visualization – self contained, fast and small.
- Html Agility Pack (HAP) is a free and open-source HTML parser written in C# to read/write DOM and supports plain XPATH or XSLT. It is a .NET code library that allows you to parse “out of the web” HTML files.
- PdfTemplating.XslFO is a C# .NET solution that tests and illustrates the capabilities of Xsl-FO for dynamically generating PDF documents.
- Skybrud.Pdf is a .NET package for generating PDFs using Formatting Objects (XSL-FO).
- FO.NET is a XSL-FO to PDF renderer written in managed C# code for the .NET framework, supporting most of XSL-FO 1.0.
- PDFSharp is the open-source .NET library that easily creates and processes PDF documents. You can create a PDF document from code, add pages, and draw graphics, text, and images using a simple drawing context.
- PdfSharpCore is a port of the PdfSharp library to .NET Core – largely removed GDI+ (only missing GetFontData – which can be replaced with freetype2).
- HtmlRenderer.PdfSharp is a cross framework (WinForms/WPF/PDF/Metro/Mono/etc.), Multipurpose (UI Controls / Image generation / PDF generation / etc.), 100% managed (C#), High performance HTML Rendering library.
- libHaru is a free, cross platform, open source library for generating PDF files. At this moment libHaru does not support reading and editing existing PDF files and it’s unlikely this support will ever appear.
- SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google’s Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
- PDFiumCore is a .NET Standard P/Invoke bindings for PDFium, which is an open-source PDF rendering engine developed by Google, used in Chromium and many other applications to work with PDF files.
- Puppeteer Sharp is a .NET port of the official Node.JS Puppeteer API. Headless Chrome .NET API
- DinkToPdf is a C# .NET Core wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to PDF.
- QuestPDF allows you to generate and edit PDF documents in your .NET applications using the open-source QuestPDF library and its C# Fluent API. Build invoices, reports and data exports with ease.
- iText is a high-performance, battle-tested library that allows you to create, adapt, inspect and maintain PDF documents, allowing you to add PDF functionality to your software projects with ease. It is also available for Java.
- Aspose.PDF is a .NET class library that allows developers to create PDF documents, whether simple or complex, on the fly programmatically.
- MuPDF.NET adds C# bindings and abstractions to MuPDF, a lightweight PDF, XPS, and eBook viewer, renderer, and toolkit. Both MuPDF.NET and MuPDF are maintained and developed by Artifex Software, Inc.
- IronPDF converts HTML to PDF in .NET 9, 8, 7, 6, Core, & Framework Generate PDFs in C# using HTML, MVC, ASPX, & Images Sign, Edit, and Read PDFs with 50+ Features
- GemBox offers fast, efficient, and easy-to-use .NET components for processing Microsoft Office documents, PDF files, email messages, and images.
- SelectPdf for .NET is a professional PDF library that can be used for creating, writing, editing, handling and reading PDF files without any external dependencies within .NET applications.
- Syncfusion is a document SDK Ideal for creating, editing, and converting documents.
The table tries to categorize the libraries by the different types listed above, mentions the used license, and gives a brief comment on the usefulness of the library for my purpose.
| Name | Type | License | Comment |
| MigraDoc | DOM & Layout | MIT ✅ | DOM and layout support are limited, but good enough for a lot of use cases |
| LiteHtmlSharp | Layout | BSD-3 ✅ | Can handle most HTML and allows easy integration with a custom renderer |
| Html Agility Pack | DOM | MIT ✅ | Fault tolerant HTML parser, but it doesn’t do layouting |
| PdfTemplating.XslFO | Layout & PDF Renderer | Apache 2.0 ✅ | Uses FO.NET or Apache FOP via Azure Function and requires XSL-FO as input |
| Skybrud.Pdf | Layout & PDF Renderer | MIT ✅ | Includes FO.NET to render PDF and has optional support for the Ibex PDF Creator |
| FO.NET | Layout & PDF Renderer | Apache 2.0 ✅ | Unmaintained PDF renderer using XSL-FO 1.0 as input |
| PDFSharp | PDF Renderer | MIT ✅ | Works well with MigraDoc, can utilize quite some memory for large documents |
| PdfSharpCore | DOM & Layout & PDF Renderer | MIT* (✅) | A port of an older version of MigraDoc and PDFSharp. It’s unclear what the capabilities are compared to the latest MigraDoc and PDFSharp versions |
| HtmlRenderer.PdfSharp | Layout & PDF Renderer | BSD-3 ✅ | Hasn’t been updated in six years and unsure how well the layouting works |
| libHaru | PDF Renderer | Zlib ✅ | It’s a C++ library with bindings for .NET, but doesn’t seem very easy to use |
| SkiaSharp | PDF Renderer | MIT ✅ | 2D graphic library, very low level, but maintained by Microsoft and Uno Platform |
| PDFiumCore | PDF Renderer | Apache 2.0 ✅ | .NET binding for the sort of industry standard C++ library for rendering PDFs maintained by Google, it’s very low-level |
| Puppeteer Sharp | Browser Engine | MIT ✅ | Downloads Chrome in the background |
| DinkToPdf | Browser Engine | MIT ✅ | Uses WebKit via wkhtmltopdf |
| QuestPDF | DOM & PDF Renderer | MIT** & Professional / Enterprise ❌ | Well maintained, but license doesn’t match |
| iText | DOM & Layout & PDF Renderer | AGPL & Commercial ❌ | Widely used, but license doesn’t match |
| Aspose.PDF | DOM & Layout & PDF Renderer | Various Commercial Options ❌ | Very well-known, but license doesn’t match |
| MuPDF.NET | PDF Viewer | AGPL & OEM Distribution & Subscription ❌ | Manipulates and displays PDFs, doesn’t allow for custom rendering, and license doesn’t match |
| IronPDF | DOM & Layout & PDF Renderer | Commercial ❌ | License doesn’t match |
| GemBox | DOM & Layout & PDF Renderer | Free*** & Commercial ❌ | Good documentation and simple API, but license doesn’t match |
| SelectPdf | Layout & PDF Renderer | Community & Commercial ❌ | While dated, it still receives updates, but license doesn’t match |
| Syncfusion | DOM & Layout & PDF Renderer | Community & Commercial ❌ | License doesn’t match |
* The dependency SixLabors.ImageSharp and SixLabors.Fonts should be licensed as Apache 2.0
** See section above regarding QuestPDF’s licensing model
*** Fully unlocked but limited to a few paragraphs
Final Boss: MigraDoc
The only option that would fit all my criteria is MigraDoc, which comes with support for PDFSharp as PDF renderer.
Technically, FO.NET could also be an option, but it hasn’t been maintained for over a decade and only implements most of the XSL-FO 1.0 standard instead of the latest 1.1 standard from 2006. Additionally, I would have to write XSL-FO, which isn’t that great of an experience.
MigraDoc is a standalone DOM library, that doesn’t have any built-in importers, meaning you can create a document object in code, but you cannot import say a Microsoft Word file or load HTML. It does however come with rendering capabilities for WPF, WinForms, RTF, and in combination with PDFSharp for PDF.
The options for the PDF creation aren’t necessarily state-of-the-art and there’s no streaming capability, which means the conversion can, especially for large reports, require a lot of memory.
In my opinion it’s a “good enough” solution. You can get pretty far. It supports text, images, tables, charts, links, paging, and more. For most “I just need a PDF export” this will be more than enough. However, once you get into the weeds of specific styles, designs, etc. MigraDoc and probably to some extend also PDFSharp show their limits. For example, if you want to change the bullet point symbol of a list, there’s no option to do so and you’d have to put together some custom style and appropriate tab stops to emulate the list behavior. Or there’s currently no way to render strike-through text and I was unable to find a workaround. Or you cannot control the letter spacing and would need to swap out the font for a condensed version, which likely gives an overall better visual, but not every font ships with different variants.
Quest Completed!
It is a bit surprising that in the vastness of the open source world there hasn’t been a real contender for PDF rendering. Okay granted, QuestPDF is really compelling and other AGPL-licensed libraries will be great fit for a lot of users.
One cannot underestimate the work required to maintain a layout or PDF rendering library and since the most demanding customers will be the ones from companies, it’s also unsurprising that maintainers do want to get paid and in fact do get paid so well, that entire companies are built around document conversion and rendering.
Very late contenders in this whole research were XSL-FO libraries like FO.NET. It seems the public has voted that XSL-FO is no longer relevant and should be replaced with HTML & CSS and thus the need to ship browser engines.
Personally, this problem has piqued my interest and I’m playing around with some ideas that may end up being open sourced and permissively licensed. The idea is about writing glue code for the existing .NET libraries with a shared interface, allowing to more easily interface between different existing and well-maintained libraries, which enables ways to convert between different file formats.
Quest Log
- Added PdfSharpCore as suggested on Hacker News

MigraDoc is indeed solid for basic reports. Had similar issues with bullet styling—ended up building a simple abstraction layer over PDFSharp for custom formatting. XSL-FO still has value for specific industries (publishing, legal), but for 90% of cases, HTML+CSS with Puppeteer/Playwright is the pragmatic choice despite the engine overhead.