PDF is the universal document format. It's also, from a developer's perspective, one of the most hostile formats to work with. The spec is 756 pages. The actual behavior is whatever Adobe Acrobat happens to do. And the SDK options range from "expensive" to "surprisingly more expensive."
PDFluent is our attempt to fix this. It's a pure Rust PDF SDK with XFA support, WebAssembly output, and pricing that doesn't require a purchase order to discover.
The problem with existing SDKs
Let's be specific. If you need to process PDFs today, your options look roughly like this:
- —iText — mature Java library, solid PDF/A support, AGPL for open-source, $10K–210K/year commercial. No rendering engine. Partial XFA via a separate add-on.
- —Apryse (PDFTron) — broad feature set, 30+ formats, strong enterprise sales. XFA support is limited to Windows-only flattening. C++ core with its associated CVE history.
- —Nutrient (PSPDFKit) — excellent mobile SDKs. No XFA whatsoever. ~€5,000/user/year average pricing.
- —Foxit — real XFA engine, 330M+ users, 15 years of production. No WASM. Contact-sales pricing.
- —PDF.js — free, open-source, great viewer. Experimental XFA. Not a processing library.
None of these is wrong — they're products built for specific markets. But there's a gap: if you need PDF rendering + XFA + WebAssembly + reasonable pricing, nothing covers all four.
The XFA problem specifically
XFA (XML Forms Architecture) was deprecated by the PDF Association in PDF 2.0, published in 2017. Adobe removed XFA support from Acrobat Reader for iOS and Android in 2021. The format is, officially, dead.
And yet. The IRS still generates XFA forms. The Dutch tax authority (Belastingdienst) uses XFA. Insurance companies, banks, and government portals across Europe and North America generate millions of XFA documents per year. "Deprecated" in a spec committee is not the same as "gone from the real world."
Processing these forms — rendering them, filling them, flattening them, extracting their data — requires a real XFA engine. Not a flattening-only add-on. Not experimental rendering that breaks on anything complex. A full implementation of XFA 3.3, including FormCalc scripting and dynamic field reflow.
Why Rust
The short answer: Rust is the only language that lets you write a PDF parser without constantly worrying about memory safety, and also compile to WebAssembly without a runtime.
PDF parsing is inherently adversarial. Real-world PDFs are broken in creative ways — overlapping xref tables, invalid object offsets, malformed streams, corrupted trailers. A C++ parser that encounters unexpected input can segfault. A Rust parser either returns an error or handles it correctly; the ownership model makes silent memory corruption impossible.
The WASM story is equally concrete. Because we have zero C/C++ dependencies in our stack, cargo build --target wasm32-unknown-unknown just works. Our complete PDF SDK — parsing, rendering, XFA engine, PDF/A validator — compiles to a ~3MB WASM bundle (2.7MB with Brotli compression). That bundle runs in any modern browser.
What PDFluent does
The SDK is organized as 38 independent Rust crates. You use what you need:
- —Parsing & rendering —
pdf-syntax,pdf-engine,pdf-render. Parse any PDF, render pages to RGBA bitmaps, extract text with position data. - —XFA —
xfa-dom-resolver,formcalc-interpreter,xfa-layout-engine,pdf-xfa. XFA 3.3: static and dynamic forms, FormCalc scripting, SOM path resolution, data import/export. - —Compliance —
pdf-compliance. PDF/A-1b through PDF/A-4, PDF/UA, ZUGFeRD/Factur-X e-invoicing. Built to pass veraPDF validation. - —Signatures —
pdf-sign. PAdES signatures with LTV (Long-Term Validation). Supports hardware tokens via PKCS#11. - —Content —
pdf-extract,pdf-redact,pdf-ocr. Text extraction with layout preservation, redaction, OCR via Tesseract bindings. - —Manipulation —
pdf-manip. Merge, split, rotate, reorder pages.
Bindings exist for C (C API), Node.js, Java, Python, and WebAssembly. You don't need to write Rust to use PDFluent.
A quick example
use pdf_engine::PdfDocument;
fn main() -> anyhow::Result<()> {
let doc = PdfDocument::open("form.pdf")?;
// Render page 0 to a PNG
let page = doc.page(0)?;
let bitmap = page.render(150.0)?; // 150 DPI
bitmap.save_png("page0.png")?;
// Flatten XFA form data
let xfa = doc.xfa()?;
let flat = xfa.flatten()?;
flat.save("form_flat.pdf")?;
Ok(())
}The same code — same binary, no changes — compiles to WASM and runs in a browser:
import init, { PdfDocument } from '@pdfluent/sdk-wasm';
await init();
const bytes = await fetch('/form.pdf').then(r => r.arrayBuffer());
const doc = PdfDocument.fromBytes(new Uint8Array(bytes));
const page = doc.page(0);
const png = page.renderToPng(150); // 150 DPI, runs client-side
const xfa = doc.xfa();
const flat = xfa.flatten();What we don't have yet
Honest list:
- —Mobile SDK — no native iOS or Android bindings. If that's a requirement, Nutrient or Foxit are better choices right now.
- —AI document extraction — no built-in LLM integration or semantic document understanding.
pdf-extractgives you structured text; what you do with it is up to you. - —Office conversion — DOCX/XLSX/PPTX output is partial. We generate valid files but complex layouts may lose fidelity.
- —Real-time collaboration — no WebSocket-based collaborative editing layer.
Pricing
All tiers include a 30-day self-serve trial — no credit card required. The Developer tier starts at €499/year for a single developer with unlimited projects. Team is €1,499/year (up to 5 developers), Business is €2,999/year (up to 15 developers), and Enterprise is €5,999/year for unlimited developers. Full details on the pricing page.
Getting started
Add to your Cargo.toml:
[dependencies]
pdf-engine = "1.0"
pdf-xfa = "1.0" # optional — XFA supportOr install the Node.js package:
npm install @pdfluent/sdk-wasmThe documentation has quickstart guides for Rust, Node.js, Python, and the WASM browser SDK. The playground lets you try it in the browser right now without installing anything.