Serverless PDF · .NET 8
Generate PDFs from HTML inside an Azure Function with no Chromium, no headless browser, and no native binaries. Bhowra.Ink renders in-process on .NET 8 — even on Windows Consumption plans, where browser-based converters can't run.
Why HTML-to-PDF is hard on Functions
The usual way to turn HTML into PDF — driving a headless browser — ships an entire Chromium engine with every deployment. Inside Azure Functions that means:
The Windows Consumption plan blocks the native APIs a Chromium process needs to launch — so browser-based converters simply fail there.
Spawning a browser per invocation adds seconds of latency and hundreds of MB to your deployment — the opposite of what serverless is for.
A bundled browser is a large, constantly-patched attack surface to track and update — on every Function you ship.
The fix — render in-process
Bhowra.Ink — a zero-dependency, serverless HTML-to-PDF library on NuGet — is pure C# on the .NET 8 base class library. There's nothing native to install, so it just runs inside your Function:
using System.Net;
using Bhowra.Ink;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
public class InvoicePdf
{
[Function("InvoicePdf")]
public async Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
{
// The HTML you want to turn into a PDF (invoice, report, statement…)
string html = await new StreamReader(req.Body).ReadToEndAsync();
// One in-process call — no Chromium, no browser to launch.
byte[] pdf = HtmlConverter.ConvertToBytes(html);
var res = req.CreateResponse(HttpStatusCode.OK);
res.Headers.Add("Content-Type", "application/pdf");
await res.Body.WriteAsync(pdf);
return res;
}
}
The same code runs unchanged on Windows Consumption, Linux, AWS Lambda, and Docker — there are no per-platform native builds to manage.
| Bhowra.Ink | Chromium-based converters | |
|---|---|---|
| Azure Functions (Windows Consumption) | ✅ Works | ❌ Blocked by sandbox |
| Native binaries | None — pure .NET 8 | Browser + driver + native libs |
| Deployment size | ~895 KB, one DLL | Hundreds of MB (full browser) |
| Cold start | ~1 s (first call, incl. JIT) | Seconds (browser spawn) |
| Memory per conversion | Tens of MB | ~0.5–1 GB per browser instance |
| Third-party dependencies | None (no AGPL) | A browser, its driver, and Node.js or native libraries |
No. Bhowra.Ink renders HTML and CSS in-process in pure .NET — there is no Chromium and no native binaries to install or a sandbox to fight.
Yes. Because there is no native code, the same managed DLL runs on Windows Consumption plans, Linux, AWS Lambda and Docker — there are no per-platform builds to manage.
There is no browser to spawn. The first call pays only normal .NET JIT (about a second); subsequent conversions run in-process and complete in well under a second.
No — by design. Bhowra.Ink renders static HTML + CSS, which is what server-generated documents (invoices, reports, statements, contracts) are. Pre-render any single-page app to HTML first.
Add Bhowra.Ink to your Functions project and convert your first document in under a minute — no browser required.