All tests run on an 8-year-old MacBook Air.
When I started building a PDF tool in Rust, the first decision was which PDF library to use.
The two main options: lopdf and pdfium-render. I chose lopdf. Here's why — and where it hurts.
The options
pdfium-render
- Bindings to Google's PDFium (the engine inside Chrome)
- Excellent rendering quality
- Large binary (~10MB added to app size)
- Requires bundling the PDFium shared library
- Great for viewing, not great for manipulation
lopdf
- Pure Rust PDF manipulation library
- No external dependencies
- Small binary footprint
- Full access to the raw object tree
- Rendering quality: you're on your own
Why lopdf won
I'm building a tool, not a viewer.
lopdf gives direct access to every object in the PDF — dictionaries, streams, cross-reference tables, the works. For operations like metadata stripping, Bates numbering, stealth watermarking, and structural rebuilding, this low-level access is exactly what you need.
pdfium would abstract all of that away.
// lopdf: direct object manipulation
doc.trailer.remove(b"Info");
for (_, object) in doc.objects.iter_mut() {
if let Ok(dict) = object.as_dict_mut() {
dict.remove(b"Author");
}
}
You can't do this with pdfium bindings. It doesn't expose the raw object tree.
Where lopdf hurts
Rendering. lopdf can't render pages to images. Zero.
My workaround: use macOS PDFKit (via a Swift sidecar) for all rendering, lopdf for all manipulation. Two engines, clear separation of responsibilities.
Complex PDF features. Heavily encrypted PDFs, some form types, certain font encodings — lopdf struggles. For a general-purpose viewer this would be a dealbreaker. For a tool focused on manipulation, it's acceptable.
The verdict
If you're building a PDF viewer: pdfium-render.
If you're building a PDF tool that manipulates document structure: lopdf.
They're solving different problems.
Hiyoko PDF Vault → https://hiyokoko.gumroad.com/l/HiyokoPDFVault
X → @hiyoyok