I got tired of every .NET HTML-to-PDF library so I built a free one from scratch
Every existing route has a real tradeoff:
Headless-browser wrappers (Puppeteer/Playwright/Chromium): huge footprint, a native browser to ship and secure, a process to spawn per render.
wkhtmltopdf wrappers: built on an unmaintained engine.
Commercial libraries: excellent, but licensed per seat/server.
"Free" libraries: AGPL (viral copyleft) or a revenue cap that becomes a license fee once you grow.
After years of working around this, I decided to build the thing I wanted. NetPDF is a real HTML/CSS layout engine written from scratch in C# - the same category as Prince or WeasyPrint, not "automate a browser."
What it is
A pure C# / .NET 10 engine that parses HTML + CSS and lays it out itself: block, inline, flexbox, grid, and tables, fragmentation across pages, paged-media (@page, margin boxes, running headers/footers, counter(page)), gradients, shadows, transforms, and SVG.
Why it's built differently
Clean-room. Every algorithm comes from the W3C / ISO / Unicode (UAX) specs, not from reading other engines' source. Legally clean to depend on.
No System.Drawing. No GDI+, no platform-specific rendering baggage.
No AGPL, no revenue caps, no commercial tier. Apache-2.0. Ship it in closed-source commercial products for free, permanently.
No browser, no native Chromium, no process spawning at render time. It's a library, not an orchestrator.
Deterministic. Same input → identical PDF bytes. Golden-file testing, content-hash caching, and byte diffs just work.
AOT-clean & fast. No reflection in hot paths; designed for PublishAot. A 3-page invoice renders in well under 200 ms; memory scales linearly with page count.
Proper international text. HarfBuzz shaping, UAX #9 bidi, UAX #14 line breaking — not naive char-by-char layout.
Try it
Package & docs: https://raroche.github.io/NetPdf/ Repo: https://github.com/raroche/NetPdf
// The gist:
HtmlPdf.Convert(html, "invoice.pdf");
I'd love your feedback
This is a solo labor of love and it's still evolving. I want to hear what breaks, what CSS you throw at it that falls over, and what you'd prioritize next. Issues, PRs, and blunt critique all welcome. If it saves you a dependency headache, that's the whole point!
A like or share would mean the world and help it reach the devs who need it.
2 comments
[ 4.4 ms ] story [ 16.7 ms ] thread