PeachPDF 0.9.5
dotnet add package PeachPDF --version 0.9.5
NuGet\Install-Package PeachPDF -Version 0.9.5
<PackageReference Include="PeachPDF" Version="0.9.5" />
<PackageVersion Include="PeachPDF" Version="0.9.5" />
<PackageReference Include="PeachPDF" />
paket add PeachPDF --version 0.9.5
#r "nuget: PeachPDF, 0.9.5"
#:package PeachPDF@0.9.5
#addin nuget:?package=PeachPDF&version=0.9.5
#tool nuget:?package=PeachPDF&version=0.9.5
PeachPDF
Peach PDF is a pure .NET HTML → PDF rendering library. This library does not depend on Puppeter, wkhtmltopdf, or any other process to render the HTML to PDF. As a result, this should work in virtually any environment where .NET 8+ works. As a side benefit of being pure .NET, performance improvements in future .NET versions immediately benefit this library.
Features
- Native vector SVG rendering (inline
<svg>, standalone<img src="x.svg">/data:image/svg+xml, and as abackground-image/list-style-imagesource) — never rasterized - CSS custom properties (
--foo) andvar(), including fallbacks and inheritance - CSS math functions:
calc(),min(),max(),clamp() - 2D and 3D CSS transforms (
translate,scale,rotate,skew,matrix, and their variants) - Flexbox layout (CSS Flexbox Level 1) and CSS Multi-column Layout
- All five CSS-wide keywords:
inherit,initial,unset,revert,revert-layer - Gradients (
linear-gradient,radial-gradient,conic-gradient, and repeating variants) with CSS Color Level 4 interpolation - CSS Paged Media:
@pagerules, named pages, margin boxes, and running headers/footers viastring-set/string() - Automatic PDF metadata extraction from HTML
<title>and<meta>elements - Optional Tagged PDF (PDF/UA) output — logical structure tree, automatic document language, CSS-driven tag mapping via
-peachpdf-pdf-tag-type(seePdfGenerateConfig.EnableTaggedPdf) - Web fonts (
@font-face), custom fonts loaded from a stream, and system font discovery — with per-character font matching (@font-faceunicode-rangeand coverage-based fallback across thefont-familystack) and monochrome emoji / supplementary-plane (astral) text viacmapformat-12 (outlines only; color-emoji tables are not embedded)
See HTML & CSS Support for the full compatibility matrix, and Supported SVG Features for the full SVG compatibility matrix.
Breaking change — spec-correct CSS pixels:
pxlengths now resolve at the CSS-specified physical ratio (1px = 1/96in = 0.75pt) everywhere — layout, borders, images, and@pagegeometry — matching browser print output. Earlier versions treated1pxas1ptfor non-font lengths, rendering px-sized content 33% larger than its true CSS size; px-derived lengths shrink by ×0.75 when upgrading. Absolute units (pt/mm/cm/in/pc) and px font sizes (which already used the correct ratio) are unaffected. See Length units.
PeachPDF Requirements
- .NET 8 or newer (every currently-supported .NET version, per Microsoft's .NET support policy)
Note: This package embeds a fork of PdfSharpCore directly in its source tree; that fork carries its own license (see src/PeachPDF/PdfSharpCore/LICENSE.md), but the end result is still open source
Installing PeachPDF
Install the PeachPDF package from nuget.org
dotnet add package PeachPDF
Using PeachPDF
Simple example
Simple example to render PDF to a Stream. All images and assets must be local to the file on the file system or in data: URIs
PdfGenerateConfig pdfConfig = new(){
PageSize = PageSize.Letter,
PageOrientation = PageOrientation.Portrait
};
PdfGenerator generator = new();
var stream = new MemoryStream();
var document = await generator.GeneratePdf(html, pdfConfig);
document.Save(stream);
Rendering an MHTML file
You can generate PDF documents using self contained MHTML files (what Chrome calls "single page documents") by using the included MimeKitNetworkLoader
PdfGenerateConfig pdfConfig = new(){
PageSize = PageSize.Letter,
PageOrientation = PageOrientation.Portrait,
NetworkLoader = new MimeKitNetworkLoader(File.OpenRead("example.mhtml"))
};
PdfGenerator generator = new();
var stream = new MemoryStream();
// Passing null to GeneratePdf will load the HTML from the provided network loader instance instead
var document = await generator.GeneratePdf(null, pdfConfig);
document.Save(stream);
Rendering HTML from a URI
You can also render HTML from the Internet to a PDF
HttpClient httpClient = new();
PdfGenerateConfig pdfConfig = new(){
PageSize = PageSize.Letter,
PageOrientation = PageOrientation.Portrait,
NetworkLoader = new HttpClientNetworkLoader(httpClient, new Uri("https://www.example.com"))
};
PdfGenerator generator = new();
var stream = new MemoryStream();
// Passing null to GeneratePdf will load the HTML from the provided network loader instance instead
var document = await generator.GeneratePdf(null, pdfConfig);
document.Save(stream);
Note that loading images using relative paths will default to the local file system unless an HttpClientNetworkLoader (or custom RNetworkLoader) with an appropriate BaseUri is provided, or if the HTML has a <base> element with an href set. Images will need to be in the current working directory when using the default loader.
Thread safety
A PdfGenerator instance is not thread-safe — don't call it concurrently from multiple threads, and don't reuse one instance across overlapping renders.
Using a separate PdfGenerator instance per thread (one per web request, one per item in a parallel batch, etc.) is safe and is the intended way to generate PDFs concurrently:
// Safe: each thread/task gets its own PdfGenerator.
var results = await Task.WhenAll(htmlDocuments.Select(async html =>
{
var generator = new PdfGenerator();
var document = await generator.GeneratePdf(html, pdfConfig);
var stream = new MemoryStream();
document.Save(stream);
return stream;
}));
See Thread safety for more detail.
Fonts
Default Font
By default, PeachPDF uses Segoe UI on Windows. Segoe UI isn't installed by default on other platforms, so PeachPDF picks a different platform-appropriate default there instead. You can remap the default font (or any other family) to another one using
PdfGenerator generator = new();
generator.AddFontFamilyMapping("Segoe UI","sans-serif"); // or any other system installed font
Generic families and system-ui
serif, sans-serif, monospace, cursive, fantasy, and system-ui resolve to a real installed font, matching actual Chromium behavior per platform (Times New Roman/Arial/Consolas/Comic Sans MS/Impact on Windows, Times/Helvetica/Menlo/Apple Chancery/Papyrus on macOS, Noto Serif/Roboto/Droid Sans Mono/Dancing Script on Android, and delegated to the system's own fontconfig on Linux) rather than one invented cross-platform table — see Fonts for the full breakdown. Every mapping, including custom ones set via AddFontFamilyMapping, is verified against what's actually installed before use.
Font weight, style, and stretch matching
A requested font-weight/font-style/font-stretch PeachPDF can't find an exact face for is matched to the nearest registered face (CSS Fonts Level 4 §5.2 — the same algorithm real browsers use), not just Regular. When nothing close enough exists, PeachPDF synthesizes a faux-bold (fill+stroke) or faux-italic/oblique (glyph shear, following an explicit oblique <angle> when declared) instead of rendering with zero visual distinction. See Fonts for details.
Adding custom fonts
The recommended way to install custom fonts is to install them into your operating system.
PeachPDF by default picks up TrueType/OpenType fonts from the operating system (%SystemRoot%\Fonts and %LOCALAPPDATA%\Microsoft\Windows\Fonts on Windows; /System/Library/Fonts, /Library/Fonts, and ~/Library/Fonts on macOS; primarily the system's own fontconfig on Linux, falling back to /usr/share/fonts, /usr/local/share/fonts, and $HOME/.fonts if fontconfig isn't available; /system/fonts, /product/fonts, and /data/fonts on Android). iOS has no system font file discovery at all — apps must embed and register their own fonts via AddFontFromStream below.
You can also add a font at runtime by loading the font into a Stream, and then using the AddFontFromStream API:
PdfGenerator generator = new();
await generator.AddFontFromStream(fontStream); // Supports TrueType (TTF), CFF, WOFF, and WOFF2 formats
Web fonts loaded via @font-face (url(), with fallback lists, and local()) are also supported.
Supported font formats
We support TrueType, CFF, WOFF, and WOFF2 font formats.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- MimeKit (>= 4.17.0)
- StbImageSharp (>= 2.30.15)
- StbImageWriteSharp (>= 1.16.7)
-
net8.0
- MimeKit (>= 4.17.0)
- StbImageSharp (>= 2.30.15)
- StbImageWriteSharp (>= 1.16.7)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.9.5 | 29 | 7/21/2026 |
| 0.9.4 | 58 | 7/20/2026 |
| 0.9.3 | 52 | 7/20/2026 |
| 0.9.2 | 196 | 7/13/2026 |
| 0.9.1 | 277 | 7/6/2026 |
| 0.9.0 | 362 | 6/30/2026 |
| 0.9.0-preview5 | 103 | 6/25/2026 |
| 0.9.0-preview4 | 100 | 6/25/2026 |
| 0.9.0-preview3 | 98 | 6/24/2026 |
| 0.8.0 | 266 | 6/18/2026 |
| 0.8.0-preview9 | 102 | 6/18/2026 |
| 0.8.0-preview8 | 88 | 6/18/2026 |
| 0.8.0-preview7 | 105 | 6/18/2026 |
| 0.8.0-preview6 | 98 | 6/18/2026 |
| 0.8.0-preview5 | 98 | 6/18/2026 |
| 0.8.0-preview4 | 104 | 6/18/2026 |
| 0.8.0-preview3 | 118 | 6/17/2026 |
| 0.8.0-preview2 | 2,768 | 10/27/2025 |
| 0.8.0-preview1 | 214 | 10/27/2025 |
| 0.7.26 | 16,338 | 10/5/2025 |