Flavor 1.0.3

dotnet add package Flavor --version 1.0.3
                    
NuGet\Install-Package Flavor -Version 1.0.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Flavor" Version="1.0.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Flavor" Version="1.0.3" />
                    
Directory.Packages.props
<PackageReference Include="Flavor" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Flavor --version 1.0.3
                    
#r "nuget: Flavor, 1.0.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Flavor@1.0.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Flavor&version=1.0.3
                    
Install as a Cake Addin
#tool nuget:?package=Flavor&version=1.0.3
                    
Install as a Cake Tool

Flavor

NuGet License .NET

HTML to PDF for .NET — free, fast, cross-platform.

var pdf = await new FlavorConverter().ConvertHtmlAsync("<h1>Hello</h1>");
await pdf.SaveAsync("hello.pdf");

Contents

Full Documentation — detailed guides, API reference, deployment examples


Install

dotnet add package Flavor
dotnet add package Flavor.AspNetCore    # optional
dotnet add package Flavor.Playwright    # optional

First run downloads Chromium (~150MB). Use BrowserExecutablePath to skip.


Why Flavor?

You can use PuppeteerSharp and PdfSharpCore directly. Flavor adds:

Without Flavor:

await new BrowserFetcher().DownloadAsync();
var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
var page = await browser.NewPageAsync();
await page.SetContentAsync(html);
await page.PdfAsync("output.pdf", new PdfOptions { Format = PaperFormat.A4 });
await browser.CloseAsync();
// + separate code for merge, watermarks, encryption...

With Flavor:

var pdf = await new FlavorConverter().ConvertHtmlAsync("<h1>Hello</h1>");
Direct libs Flavor
Browser lifecycle Manual Managed
Browser reuse DIY Built-in pool
ASP.NET Core Boilerplate this.Pdf()
Merge/Split/Watermark Different APIs Unified
Resource cleanup Easy to leak Automatic

When to skip Flavor: single simple use-case, need full browser control, already have your own wrapper.


Quick Start

// HTML
var pdf = await converter.ConvertHtmlAsync("<h1>Hello</h1>");

// URL
var pdf = await converter.ConvertUrlAsync("https://example.com");

// With options
var pdf = await converter.ConvertHtmlAsync(html, o => o
    .WithPageSize(PageSize.A4)
    .WithMargins(Margins.Normal)
    .WithBackground());

Options

// Page sizes
.WithPageSize(PageSize.A4)
.WithPageSize(new PageSize(8.5, 11))  // custom inches

// Margins
.WithMargins(Margins.None)
.WithMargins(new Margins(1, 0.5, 1, 0.5))  // top, right, bottom, left

// Headers/Footers
.WithHeader("<div style='font-size:10px'><span class='title'></span></div>")
.WithFooter("<div>Page <span class='pageNumber'></span> of <span class='totalPages'></span></div>")

// Wait for JS
.WithWaitCondition(WaitCondition.NetworkIdle0)
.WithWaitDelay(TimeSpan.FromSeconds(1))

ASP.NET Core

// Program.cs
builder.Services.AddFlavorAspNetCore();
builder.Services.AddFlavorWarmup();  // optional, reduces first-request latency
// Controller
[HttpGet("invoice")]
public IActionResult GetInvoice()
{
    return this.Pdf("<h1>Invoice</h1>", "invoice.pdf");
}

[HttpGet("report")]
public IActionResult GetReport()
{
    return this.PdfFromView("Reports/Template", model, "report.pdf");
}

PDF Operations

using Flavor.Operations;

// Merge
var merged = PdfMerger.Merge(pdf1, pdf2, pdf3);

// Split
var pages = PdfSplitter.SplitToPages(document);
var extracted = PdfSplitter.ExtractPages(document, 1, 3, 5);

// Watermark
var marked = PdfWatermark.AddText(document, "DRAFT");
var marked = PdfWatermark.AddText(document, o => o
    .WithText("CONFIDENTIAL")
    .WithOpacity(0.3)
    .WithRotation(-45));

// Page numbers
var numbered = PdfPageNumbers.Add(document);

Security

using Flavor.Security;

// Password protect
var encrypted = PdfSecurity.Encrypt(document, "secret");

// With permissions
var encrypted = PdfSecurity.Encrypt(document, new PdfSecurityOptions
{
    UserPassword = "view",
    OwnerPassword = "edit",
    AllowPrinting = false
});

Playwright

Alternative to PuppeteerSharp. Supports Firefox and WebKit.

dotnet add package Flavor.Playwright
pwsh bin/Debug/net8.0/playwright.ps1 install
builder.Services.AddFlavorWithPlaywright(PlaywrightBrowserType.Firefox);

Performance

Browser pool for concurrent requests:

builder.Services.AddFlavor(o => o.PoolSize = 4);
Pool Throughput
1 ~8 PDF/sec
2 ~12 PDF/sec
4 ~18 PDF/sec

System Requirements

Uses real browser engine = heavy dependencies.

Browser ~150MB, auto-downloaded
Memory ~150MB per instance
Linux Needs system libs (see Docker)

Deployment

Docker

FROM mcr.microsoft.com/dotnet/aspnet:8.0

RUN apt-get update && apt-get install -y chromium \
    fonts-liberation libasound2 libatk-bridge2.0-0 libcups2 \
    libdrm2 libgbm1 libgtk-3-0 libnspr4 libnss3 \
    libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
    && rm -rf /var/lib/apt/lists/*

ENV FLAVOR_BROWSER_PATH=/usr/bin/chromium

Kubernetes

resources:
  limits:
    memory: "1Gi"
env:
  - name: Flavor__PoolSize
    value: "2"

Scale pods, not pool size.

Azure

// App Service
options.BrowserArgs = ["--no-sandbox", "--disable-dev-shm-usage"];

// Functions: use Premium Plan or Container Apps

AWS Lambda

250MB limit. Use Lambda Layer with Chrome, or better — Fargate.


Contributing

I appreciate feedback and contribution to this repo!

License

Apache 2.0


Built on PuppeteerSharp, Playwright, PdfSharpCore.

Product 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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Flavor:

Package Downloads
Flavor.AspNetCore

ASP.NET Core integration for Flavor HTML to PDF converter. Includes PdfResult, Razor view rendering, and DI extensions.

Flavor.Playwright

Playwright-based rendering engine for Flavor HTML to PDF converter. Alternative to the default Chromium engine.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.3 195 2/3/2026
1.0.2 166 1/19/2026
1.0.1 164 1/19/2026
1.0.0 161 1/18/2026