| Crates.io | pdfium |
| lib.rs | pdfium |
| version | 0.10.2 |
| created_at | 2025-07-14 16:48:22.498894+00 |
| updated_at | 2026-01-11 19:38:58.789166+00 |
| description | Modern Rust interface to PDFium, the PDF library from Google |
| homepage | https://github.com/newinnovations/pdfium-rs |
| repository | https://github.com/newinnovations/pdfium-rs |
| max_upload_size | |
| id | 1752030 |
| size | 920,794 |
A modern, streamlined Rust interface to the PDFium C library, designed for simplicity and thread safety in interactive applications. PDFium is Google's PDF library developed for (and used in) the Chromium and Chrome web browsers.
Skia or AGG (Anti-Grain Geometry) as renderer for PDFiumWhile existing PDFium bindings for Rust are available, this crate takes a different approach focused on ease of use and thread safety:
This library uses a modern, static, and thread-safe initialization pattern with parking_lot::ReentrantMutex. On first use, it checks for the availability of the PDFium dynamic library on your system or in a specified directory, and stores the library reference statically for the application's lifetime. This eliminates the need for complex library management and prevents deadlocks when used multiple times in the same thread.
Unlike other implementations, this crate doesn't impose lifetimes on structs representing documents, pages, bitmaps, and other structures. This makes integration into your application much simpler - you can store these objects wherever you need them without fighting the borrow checker. They are even clonable. This makes it ideal for interactive use cases, such as PDF viewers, editors, and other real-time applications.
unsafe FunctionsWhile most users will be using the high-level idiomatic Rust abstractions, PDFium-rs does provide safe public access to the entire C API with full documentation. Unsafe pointers to C structures and memory have been transparently replaced with their Rust counterparts. This feature makes it also possible to seamlessly mix idiomatic Rust functions with the C API functions.
PDFium-rs serves as one of the two PDF engines behind MView6, a PDF and photo viewer written in Rust and GTK4 by the same author. With a single keypress, you can switch engines and compare the rendering quality differences between mupdf and PDFium.
use pdfium::*;
struct App {
doc: PdfiumDocument,
}
impl App {
pub fn new(filename: &str) -> PdfiumResult<Self> {
Ok(App {
doc: PdfiumDocument::new_from_path(filename, None)?,
})
}
pub fn render_to_file(&self, filename: &str, index: i32) -> PdfiumResult<()> {
let page = self.doc.page(index)?;
let config = PdfiumRenderConfig::new().with_height(1080);
let bitmap = page.render(&config).unwrap();
bitmap.save(filename, image::ImageFormat::Png)
}
}
fn main() -> PdfiumResult<()> {
let app = App::new("resources/groningen.pdf")?;
app.render_to_file("groningen-page-1-rust.png", 0)
}
The quick start example already shows PDFium-rs is easy with lifetimes: a PdfiumDocument can be stored in a struct without lifetime issues. The same applies to all other PDFium-rs structs.
They are also clonable and the library will track their usage and close when possible, as shown below:
use pdfium::*;
let document = PdfiumDocument::new_from_path("resources/groningen.pdf", None).unwrap();
let page = document.page(0).unwrap();
drop(document); // Demonstrate that the page can be used after the document is dropped.
let config = PdfiumRenderConfig::new().with_height(1080);
let bitmap = page.render(&config).unwrap();
bitmap.save("groningen-drop-demo.jpg", image::ImageFormat::Jpeg);
This is the same example as the quick start, but now using the C API of PDFium directly.
unsafe code blocks in your codelib] or [try_lib]bitmap.save operationuse pdfium::*;
struct App {
doc: PdfiumDocument,
}
impl App {
pub fn new(filename: &str) -> PdfiumResult<Self> {
Ok(App {
doc: PdfiumDocument::new_from_path(filename, None)?,
})
}
pub fn render_to_file(&self, filename: &str, index: i32) -> PdfiumResult<()> {
let page = lib().FPDF_LoadPage(&self.doc, index)?;
let mut left = 0.0;
let mut bottom = 0.0;
let mut right = 0.0;
let mut top = 0.0;
lib().FPDFPage_GetMediaBox(&page, &mut left, &mut bottom, &mut right, &mut top)?;
let height = 1080;
let scale = height as f32 / (top - bottom);
let width = ((right - left) * scale) as i32;
let matrix = pdfium_types::FS_MATRIX {
a: scale,
b: 0.0,
c: 0.0,
d: scale,
e: 0.0,
f: 0.0,
};
let bitmap = lib().FPDFBitmap_Create(width, height, 1)?;
lib().FPDFBitmap_FillRect(&bitmap, 0, 0, width, height, 0xffffffff)?;
let clipping = pdfium_types::FS_RECTF {
left: 0.0,
top: height as f32,
right: width as f32,
bottom: 0.0,
};
lib().FPDF_RenderPageBitmapWithMatrix(&bitmap, &page, &matrix, &clipping, 0);
bitmap.save(filename, image::ImageFormat::Png)?;
Ok(())
}
}
fn main() -> PdfiumResult<()> {
let app = App::new("resources/groningen.pdf")?;
app.render_to_file("groningen-page-1-c.png", 0)
}
You can find more information on how to use PDFium-rs in the examples/ directory.
Add this to your Cargo.toml:
[dependencies]
pdfium = "0.10.2" # Check crates.io for the latest version
For the latest version, visit crates.io or use cargo search pdfium.
PDFium-rs requires the PDFium dynamic library to be available on your system:
libpdfium.sopdfium.dlllibpdfium.dylibPre-built libraries for all major platforms are available from: https://github.com/bblanchon/pdfium-binaries/releases
Choose the appropriate build for your target platform and architecture (x64, arm64, etc.).
/usr/lib/, /usr/local/lib/, or /usr/lib/your_app//usr/local/lib/ or /opt/homebrew/lib/set_library_location] to specify custom pathspdfium.dll in the same directory as your executableuse pdfium::*;
// Set custom library path before first use
set_library_location("/path/to/your/pdfium/library/");
// Your application code...
let doc = PdfiumDocument::new_from_path("document.pdf", None);
Skia or AGGPDFium currently supports two rendering backends. You can select Skia over AGG (Anti-Grain Geometry) using the [set_use_skia] function:
use pdfium::*;
// Use Skia renderer (must be called before first PDFium usage)
set_use_skia(true);
// Your application code...
let doc = PdfiumDocument::new_from_path("document.pdf", None);
All platforms require their respective PDFium dynamic libraries.
/// Error loading or initializing the PDFium library
PdfiumError::LibraryError(String)
ldd libpdfium.soset_library_location] to specify the exact pathpdfium.dll is in your PATH or application directoryxattr -d com.apple.quarantine libpdfium.dylibThis might indicate an incompatible PDFium library version. Try downloading a different build from the pdfium-binaries releases.
If you encounter issues not covered here:
This crate is actively being developed and already implements a safe Rust interface to the full C API (all 440+ fuctions).
The idomatic abstraction is focused on a subset of PDFium's functionality. While it covers the core rendering and document manipulation features needed for most interactive applications, it doesn't (yet) provide the complete feature set.
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
After cloning the repository, install the git hooks:
./scripts/install-hooks.sh
PDFium-rs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.