A PDF library to remove
PdfNetStack started with a client. Their .NET software depended on a third-party PDF library, and they wanted to get rid of it. We helped them do that, and we wrote PdfNetStack during that work.
Removing a PDF library looks like a small job. It rarely is. A PDF library often ends up called from all over an application, and every call has to be found before you can decide what replaces it.
Today PdfNetStack is a general-purpose PDF library for .NET. It is published on NuGet under the MIT license, and we maintain it for the whole .NET community.
Starting from the specification
PDF is a documented format. Its specifications are published, and we wrote PdfNetStack from them. It is original work, in pure managed C#.
One decision shaped everything else: no native binaries. PdfNetStack does not call Ghostscript, does not start a browser and ships no native library. The OCR add-on is the one exception: it runs its models on ONNX Runtime.
That decision sets where the code can run. The library targets net8.0 and net10.0 with no dependencies, and stays compatible with trimming and Native AOT. It runs in AWS Lambda, in Azure Functions and in a container. A netstandard2.0 target covers older applications: .NET Framework 4.6.2 to 4.8.1, Mono and Unity. CI runs the tests on .NET Framework 4.8, .NET 8 and .NET 10, on Windows, Linux and macOS.
What PdfNetStack does today
The core covers what business software usually asks of a PDF:
- Compression, lossless: object streams, compressed cross-reference streams, unreachable object removal, Flate recompression, PNG prediction, lossless JPEG re-encoding, deduplication. Image downsampling and lossy JPEG are opt-in, behind a perceptual quality gate.
- Pages: merge, split, reorder, rotate.
- Large files: opened on demand with bounded memory, and incremental saves that keep signatures valid.
- Security: AES-256 and AES-128 encryption, PAdES signatures from B-B to B-LTA, and their validation.
- Content: drawing, images, annotations, OpenType, WOFF2 and variable fonts, with Arabic and right to left text.
- AcroForm forms: fill, flatten, create.
- Archiving and invoicing: PDF/A-2 and PDF/A-3, Factur-X and ZUGFeRD invoices.
- Extraction of text and images.
Two add-ons cover the rest when you need them. PdfNetStack.Html turns HTML and CSS into PDF without a browser, with flex, grid, tables, paged media and web fonts. PdfNetStack.Ocr makes scans searchable. For the command line there is PdfNetStack.Tool.
The proof: every compression is checked
A compressed file that no longer says the same thing is worse than a heavy one. An invoice missing an amount, or a contract with a page that renders wrong, does not show up at compression time. Someone finds it later.
So PdfNetStack does not trust its own optimizer. After a pass, it reads back the file it just wrote and compares it to the source, object by object. Streams are decoded before the comparison. JPEG images are compared DCT coefficient by DCT coefficient. If anything differs, you get your original bytes.
Signed and encrypted files follow a simpler rule: the optimizer never rewrites them. A signature covers specific bytes, and rewriting the file would break it.
Lossless is the default. The lossy options exist, but you have to ask for them, and they go through a perceptual quality gate.
The numbers
We publish a benchmark anyone can reproduce. On every release, CI downloads 77 openly licensed or public domain PDFs: documents from NIST and NASA, arXiv papers, government gazettes, test files.
Release 1.1.0, run on 5 November 2026 on a 4 core Linux runner:
- lossless default: 196.6 MiB down to 172.9 MiB, 12.1% saved
- balanced preset: 23.4% saved
- lossy profile: 29.5% saved
- zero failures, and the checked pages of every lossless output render identically in PDFium
At 1.0.0 we also ran a private corpus of 1,296 real world files: 569 MiB of invoices, reports, manuals, scans and presentations. 1,003 files came out optimized, with 17.6% saved. Zero verification failures and zero differing pixels at 150 DPI across 2,161 pages, in about 65 seconds on 8 cores.
The private corpus is not published. The public benchmark is the one to rely on: anyone can rerun it, and every release runs it again.
What about commercial SDKs?
Apryse, formerly PDFTron, sells a commercial PDF SDK, and other vendors do the same. PdfNetStack is not related to PDFNet, the Apryse SDK, despite the similar name.
We have not measured PdfNetStack against those SDKs, so we publish no comparison figures. On some specific tasks we still think it does better, and every reason can be checked on PdfNetStack itself:
- the MIT license, with no license key and no per-deployment fee
- pure managed C#, with no native binaries
- every compressed file is proved equivalent to its source, and the original comes back if anything differs
- signed and encrypted files are never rewritten by the optimizer
- it runs in AWS Lambda, Azure Functions and containers, with trimming and Native AOT
For your own case, the best comparison is your own files. The library installs with one command.
Why open source, and why MIT
We could have kept this code for our own engagements. We published it because a PDF library gets better with the files people give it, and other teams will give it files we would never have seen.
MIT is a short, permissive license: commercial use included, with no license key and no per-deployment fee. Nobody has to write to us before using it. Our job is designing and evolving software for clients, and a library other teams use teaches us more than a license sale would.
1.0.0 was published on NuGet on 28 October 2026, and 1.1.0 on 5 November. On 12 November, NuGet counted 1,519 downloads across the six packages, 1,010 of them for PdfNetStack. Those counts include automated downloads, so they say nothing about how many teams use it.
Get started
Add the package to your project:
dotnet add package PdfNetStackTo compress files without writing code, install the command line tool:
dotnet tool install -g PdfNetStack.Tool
pdfnetstack optimize in.pdf out.pdfThe documentation is at jadev-corp.com/pdfnetstack, the source code on GitHub and the packages on NuGet.
What comes next
The documentation site opens with this post. Every new release runs the public benchmark in CI again. If a file misbehaves, the GitHub repository is where to tell us.
And if your .NET application depends on a PDF SDK you want to leave, that is work we know how to do. It is part of our business software modernization offer. The project itself is described on its reference page.

