Migrate from PDFBox, Poppler, C++, Java, and pdf-rs

This guide provides specific instructions for developers to migrate their existing PDF projects from other libraries to the PDFluent SDK in Rust.

Migrate from Apache PDFBox to PDFluent

A step-by-step guide for replacing Apache PDFBox with PDFluent. Covers dependency setup, document loading, text extraction, form filling, and saving.

  1. Replace the dependency

    Remove PDFBox from pom.xml or build.gradle and add pdfluent to Cargo.toml.

  2. Open a document

    PDFBox uses PDDocument.load() with a File or byte array. PDFluent uses Document::open which returns a Result.

  3. Extract text

    PDFBox requires a PDFTextStripper instance and produces a single string for the whole document. PDFluent extracts per-page.

  4. Fill AcroForm fields

    PDFBox accesses fields through PDDocumentCatalog and PDAcroForm. PDFluent uses a direct acroform() handle.

  5. Save and close

    PDFBox requires explicit close(). PDFluent drops the document when it goes out of scope; call save() to write.

  • PDFBox page numbers are 1-indexed in PDFTextStripper but 0-indexed in PDPageTree. PDFluent always uses 0-indexed.
  • PDFBox does not support XFA forms. If your PDFs use XFA, PDFluent handles them natively.
  • PDFBox PDDocument must be closed explicitly or resource leaks occur. PDFluent documents drop cleanly with Rust ownership.

From Poppler to PDFluent

Poppler is a GPL-licensed C++ library. PDFluent is a commercially licensed Rust crate — no C++ compilation step, no copyleft to propagate, and a higher-level API.

  1. Remove the C++ Poppler dependency

    Poppler is a system library installed via apt, brew, or built from source. It requires C++ headers and a linker step in your build. PDFluent is a Rust crate — add it to Cargo.toml and Cargo handles everything. No system package required, no pkg-config, no build.rs linking.

  2. Replace Poppler document loading with Document::open

    Poppler's C++ API returns raw pointers from load_from_file. You must check for null and remember to delete the document when done. PDFluent returns a Result. The ? operator handles errors, and the document is freed when it goes out of scope.

  3. Verify your GPL licensing obligations are resolved

    Poppler is licensed under GPL-2.0. Any software that links against it as a library must also be GPL-licensed or obtain a separate commercial exception. PDFluent ships under a commercial license with no copyleft, so linking it never forces your own code open — no GPL propagation.

  • Poppler focuses on rendering and text extraction. If your primary use case is pixel-accurate PDF rendering, review PDFluent's current rendering capabilities before migrating.
  • Poppler does not support creating or editing PDFs — it is read-only. If you use additional tools (like libqpdf or Cairo) alongside Poppler for writing, PDFluent handles both reading and writing in a single crate.
  • Poppler uses 0-based page indexing, matching PDFluent's 0-based indexing. Page number references do not need adjustment.
  • Poppler has no form-filling API. AcroForm and XFA support require a separate library when using Poppler.

From C++ PDF to Rust

A guide for C++ developers moving from libpoppler, MuPDF, or custom PDF code to PDFluent. Same performance, no manual memory management, and memory-safe by construction.

  1. Replace manual memory management with ownership

    C++ PDF code allocates and frees objects manually. Poppler hands you raw pointers; you decide when to delete them. In Rust, the compiler tracks ownership at compile time. Values are freed when they go out of scope. There are no delete calls and no use-after-free bugs.

  2. Replace raw pointer APIs with safe method calls

    C++ PDF libraries pass raw pointers for page objects, text content, and annotations. You must check for null pointers at every step. PDFluent methods return Option or Result — the compiler forces you to handle the failure case, eliminating null pointer crashes.

  3. Migrate build configuration from CMake to Cargo

    C++ projects link against poppler or MuPDF through CMake or pkg-config. Cargo handles all dependency resolution automatically. Remove the C++ library linkage from your build scripts and add PDFluent to Cargo.toml.

  • Poppler is GPL-licensed. If your C++ code links against it, your application must also be GPL-licensed. PDFluent is commercially licensed with no copyleft — check your licensing obligations before and after migration.
  • MuPDF has a custom Affero GPL license for open-source use and a commercial license for proprietary use. PDFluent offers transparent published pricing with no per-seat fees.
  • C++ page indexing varies by library. PDFluent uses 0-based page indexing consistently.
  • If you have C++ code that calls Poppler through a wrapper, you can introduce PDFluent incrementally via its C API before fully migrating.

From Java PDF to Rust

A guide for Java developers moving any Java PDF library — iText, PDFBox, or similar — to PDFluent in Rust. Covers the ownership model, error handling, and deployment changes.

  1. Map your Java PDF operations to PDFluent equivalents

    Java PDF libraries use object graphs you mutate through method calls. PDFluent exposes the same operations — open, read, fill, save — through a Rust API. Start by listing every PDF operation your code performs and find the PDFluent equivalent in the docs.

  2. Handle errors with Result instead of checked exceptions

    Java PDF libraries throw checked exceptions — you surround every call with try/catch and manage cleanup in finally blocks. Rust uses the Result type. The ? operator propagates errors up the call stack automatically, and ownership ensures resources are freed when values go out of scope. There is no finally block because there is no need for one.

  3. Replace JVM deployment with a static binary

    A Java PDF service requires a JVM at the deployment target, adds 200-400 MB to your Docker image, and incurs a 1-3 second cold start. A Rust binary compiled with PDFluent has no runtime dependency and cold-starts in milliseconds. Build with cargo build --release and copy the single binary to your target.

  • Java libraries use 1-based page indexing. PDFluent uses 0-based indexing — page(0) is the first page.
  • iText 7 is AGPL-licensed. If you are migrating partly to escape licensing constraints, verify your current obligations before removing iText.
  • PDFBox's PDDocument.load() accepts byte arrays in addition to files. PDFluent's PdfDocument::from_bytes() is the equivalent.
  • The Rust ownership model prevents use-after-free bugs that are possible in Java when document references are held after close() is called.

Migrate from pdf-rs to PDFluent

Both libraries are written in Rust. pdf-rs is read-only. If you need to write, fill forms, sign, or validate PDFs, switch to PDFluent.

  1. Replace the dependency in Cargo.toml

    Remove pdf from Cargo.toml and add pdfluent. Both are pure Rust, so there are no native library changes.

  2. Open a PDF for reading

    pdf-rs uses FileOptions to open a file. PDFluent uses Document::open. The error handling model is the same — both return Results.

  3. Extract text from pages

    pdf-rs requires traversing content streams manually. PDFluent provides a high-level text() method per page.

  4. Write and modify PDFs

    pdf-rs has no write API. PDFluent supports modifying existing documents, filling forms, adding annotations, and saving. This step has no pdf-rs equivalent.

  • pdf-rs uses cached file access by default. PDFluent loads the document into memory. For very large files, use Document::open_streaming().
  • pdf-rs has incomplete support for some encrypted PDFs and complex content streams. PDFluent handles these cases.