CobaltPDF.WebKit (WebKit edition)
Tip
CobaltPDF.WebKit has its own full documentation site — configuration, deployment (validated Azure Functions / App Service / Docker walkthroughs), the bundle system, and API reference: WebKit edition docs.
CobaltPDF.WebKit is a separate, standalone library that renders HTML to PDF with WebKit instead of Chromium. It is drop-in API-compatible with CobaltPDF — the same CobaltEngine type, the same fluent methods, the same PdfDocument result. One CobaltPDF license key activates both libraries.
dotnet add package CobaltPdf.WebKit
using CobaltPdf.WebKit; // the only line that differs from CobaltPDF
var pdf = await new CobaltEngine()
.WithPaperFormat("A4")
.RenderUrlAsPdfAsync("https://example.com");
await pdf.SaveAsAsync("out.pdf");
Switching an existing CobaltPDF project to WebKit is a one-line change: swap using CobaltPdf; for using CobaltPdf.WebKit; and recompile — the rest of your code is unchanged.
Compatibility runs in both directions: engine-specific knobs exist on both libraries
as accepted no-ops on the other. WithoutPostProcessing() (a WebKit raw-output mode that
trades larger files for lower memory) is callable here too — Chromium's PDF backend
already subsets fonts and compresses images natively, so it simply has no effect. Likewise
the WebKit edition accepts Chromium's ExtraArgs flags and ignores them. Code written
against either engine compiles and runs against the other unchanged — see
Configuration.
Why WebKit?
Memory and speed. On the benchmark workload — 10 warm renders of example.com, wikipedia.org/Portable_Document_Format, and news.ycombinator.com, with steady RSS sampled after each render returned and the full subprocess tree included — the WebKit edition idles at ~14 MB steady RSS vs ~310 MB for Chromium (up to 96% less) and renders 57% faster warm-mean:
| Metric | CobaltPDF (Chromium) | CobaltPDF.WebKit | Δ |
|---|---|---|---|
| Warm-mean render time | 5,747 ms | 2,456 ms | 57% faster |
| Steady cold RSS | 294 MB | 14 MB | 95% less memory |
| Steady warm-mean RSS | 310 MB | 14 MB | 95% less memory |
| Steady warm-max RSS | 315 MB | 14 MB | 96% less memory |
On memory-capped hosts (Azure App Service B-series, container plans with 1.5–3.5 GB limits), that headroom is the difference between "works reliably" and "OOM-killed on image-heavy pages."
Platform Support
| Host | How it runs |
|---|---|
| Linux x64/arm64 (glibc or musl) — production | Inline self-provisioning bundle — downloads, SHA-256-verifies and extracts a portable WebKit bundle on first use. No Docker, no apt install, no system setup. |
| Windows development — WSL2 (recommended) | Provisions the bundle inside your default WSL distro on first render and spawns WebKit via wsl.exe. Same code, same memory profile as Linux production. |
| Windows / macOS development — Docker Desktop | Auto-pulls a dev image and runs the same render code in a container. |
| Offline development — opt-in stub mode | Returns a placeholder PDF for unit-testing controllers and wiring without real WebKit (Debug builds). |
Air-Gapped / Offline Deployments
Three options when the runtime cannot reach the public bundle URL:
- Ship the bundle in your publish output — drop a pre-extracted bundle at
AppContext.BaseDirectory/cobalt-webkit-bundle/. The library auto-discovers it before any download attempt; no code or env-var setup. - Point at a pre-extracted bundle on disk — set the
COBALT_INLINE_HOMEenvironment variable to the bundle directory; provisioning is skipped entirely. - Self-host the tarball — upload the bundle tarball to a private feed (Artifactory, S3, etc.) and point
PoolOptions.BundleBaseUrlat it:
CobaltEngine.Configure(o =>
{
o.BundleBaseUrl = "https://artifactory.internal/cobalt-webkit/";
});
Pool Tuning & Memory Metrics
MaxUsesPerBrowser (default 5) is the most important knob: it recycles the WebKit worker after N renders, which bounds the worker's resident set. Raise it (e.g. 20) to favour throughput; lower it on tightly memory-constrained hosts at the cost of paying the cold-start more often.
CobaltEngine.Configure(o =>
{
o.MinSize = 1; // workers kept warm
o.MaxSize = 5; // concurrent renders cap
o.MaxUsesPerBrowser = 5; // recycle after N renders — bounds RSS
});
Every render exposes peak and steady RSS for observability via PdfDocument.PeakRssBytes and PdfDocument.SteadyRssBytes (with PeakRssMb / SteadyRssMb conveniences):
var pdf = await engine.RenderUrlAsPdfAsync("https://example.com");
Console.WriteLine($"Peak RSS: {pdf.PeakRssMb:F0} MB (transient, during render)");
Console.WriteLine($"Steady RSS: {pdf.SteadyRssMb:F0} MB (after WebKit children exited)");
Use steady RSS to size your host's memory limit — peak is a brief transient during page-load and PDF serialisation.
Which Engine Should I Choose?
| Choose | When |
|---|---|
| CobaltPDF (Chromium) | Maximum rendering fidelity, bleeding-edge CSS features, or native Windows production hosting. |
| CobaltPDF.WebKit | High-volume, memory-sensitive Linux workloads — invoices, receipts, statements — and as a modern replacement for wkhtmltopdf. |
Feature Parity
The WebKit edition supports the same fluent feature set as the Chromium edition:
- Browser pooling and pre-warming
- Headers, footers & watermarks — including rasterized watermarks
- Cookies & web storage
- HTTP headers & User-Agent
- Wait strategies
- Custom JavaScript
- Fonts
- Lazy loading
- Metadata
- AES-256 encryption
- Page splitting & merging
- CobaltPDF.Requests microservice support
Licensing
One CobaltPDF license key activates both CobaltPDF and CobaltPDF.WebKit — see Licensing.