How to Use pdf‑inspector WebAssembly: A Complete Guide to Browser‑Native PDF Processing
pdf‑inspector WebAssembly lets you run the full Rust PDF analysis engine directly in the browser, processing PDFs client‑side without sending bytes to any server.
The firecrawl/pdf-inspector repository ships a lightweight WASM bundle built with wasm‑bindgen, exposing a synchronous JavaScript API for PDF classification, Markdown extraction, and text processing. This guide walks through the architecture, installation, and practical usage patterns based on the actual source code implementation.
WebAssembly Module Architecture
The WASM binding layer lives in [wasm/src/lib.rs](https://github.com/firecrawl/pdf-inspector/blob/main/wasm/src/lib.rs) and follows a clean separation between JavaScript interop and core Rust logic.
TypeScript Type Generation
The module embeds custom TypeScript definitions via #[wasm_bindgen(typescript_custom_section)] (source line 8‑66). This provides IDE autocomplete for processPdf options including pages, password, profile, and includePageMarkers.
Option Handling Pipeline
Two functions bridge JavaScript inputs to Rust internals:
deserialize_options(source line 78‑84) — ConvertsJsValueintoWasmProcessOptions, gracefully handlingundefined/null.build_options(source line 86‑118) — MapsWasmProcessOptionsto corePdfOptions, validating 1‑indexed page numbers and convertingprofilestrings ("fidelity"or"compact") to theMarkdownProfileenum.
Processing Entry Point
The process_pdf function (source line 29‑40) orchestrates execution:
- Calls
initialize()to installconsole_error_panic_hookfor readable JavaScript stack traces (source line 25‑27). - Builds
PdfOptionswithProcessMode::Full. - Measures timing via
js_sys::Date::now(). - Delegates to
pdf_inspector::process_pdf_mem_with_options(source line 35‑36). - Wraps results in
WasmPdfProcessResultand serializes to JavaScript.
All exported functions—detectPdf, classifyPdf, extractText, and version—follow this same pattern, varying only in ProcessMode and return shape.
WebAssembly API Reference
| Export | Description | Process Mode |
|---|---|---|
processPdf(data, options?) |
Full classification + structured Markdown extraction | Full |
detectPdf(data, options?) |
Classification only, no Markdown | Detect |
classifyPdf(data) |
Lightweight classification matching Node.js API shape | Classify |
extractText(data) |
Plain text without Markdown formatting | Extract |
version() |
Returns WASM package version string | — |
After the initial asynchronous init() call to load the binary, all functions are synchronous—enabling straightforward integration in UI components or Web Workers.
Installing and Initializing pdf‑inspector WebAssembly
Add the package via npm:
npm install @firecrawl/pdf-inspector-wasm
The entry point exports an init function that must be called once before using any processing functions:
import init, { processPdf, detectPdf, classifyPdf, extractText, version } from "@firecrawl/pdf-inspector-wasm";
async function initialize() {
// Required: loads the .wasm binary into memory
await init();
console.log("WASM ready, version:", version());
}
initialize();
Processing PDFs in the Browser: Code Examples
Full Processing with Markdown Extraction
Load a PDF via fetch and extract structured Markdown:
import init, { processPdf } from "@firecrawl/pdf-inspector-wasm";
async function extractMarkdown(pdfUrl: string) {
await init();
const response = await fetch(pdfUrl);
const pdfBytes = new Uint8Array(await response.arrayBuffer());
const result = processPdf(pdfBytes);
console.log("PDF type:", result.pdfType); // "TextBased" | "Scanned" | "Mixed" | "ImageBased"
console.log("Pages needing OCR:", result.pagesNeedingOcr);
console.log("Markdown:", result.markdown); // Structured markdown string
console.log("Processing time (ms):", result.durationMs);
return result;
}
Lightweight Detection Only
For scenarios where you only need classification without extraction:
import init, { detectPdf } from "@firecrawl/pdf-inspector-wasm";
async function quickDetect(pdfBytes: Uint8Array) {
await init();
const result = detectPdf(pdfBytes);
// result contains pdfType, pageCount, confidence scores
console.log("Detected:", result.pdfType);
return result;
}
Selective Page Processing with Options
Process specific pages and choose output formatting:
import init, { processPdf } from "@firecrawl/pdf-inspector-wasm";
async function selectiveExtract(pdfBytes: Uint8Array) {
await init();
const options = {
pages: [1, 3, 5, 7, 9], // 1-indexed page numbers
profile: "compact", // "fidelity" or "compact"
includePageMarkers: true, // Insert `<!-- Page N -->` markers
password: undefined, // Optional: decryption password
};
const result = processPdf(pdfBytes, options);
console.log(result.markdown);
}
Plain Text Extraction
Skip Markdown formatting entirely:
import init, { extractText } from "@firecrawl/pdf-inspector-wasm";
async function getPlainText(pdfBytes: Uint8Array) {
await init();
const text = extractText(pdfBytes);
// Returns raw concatenated text without structural formatting
return text;
}
Node.js‑Compatible Classification
Match the API shape used by server‑side bindings:
import init, { classifyPdf } from "@firecrawl/pdf-inspector-wasm";
async function classify(pdfBytes: Uint8Array) {
await init();
const classification = classifyPdf(pdfBytes);
// Minimal shape: { pdfType, confidence, isScanned, pageCount }
return classification;
}
Client‑Side Security Model
The parser runs entirely within the browser—no PDF bytes are transmitted to external servers (source line 45‑48 of the WASM README). This architecture suits:
- Privacy‑sensitive document processing
- Healthcare or financial applications with compliance requirements
- Offline‑capable web applications
Key Source Files
| File | Purpose |
|---|---|
[wasm/README.md](https://github.com/firecrawl/pdf-inspector/blob/main/wasm/README.md) |
Installation, build instructions, and security notes |
[wasm/src/lib.rs](https://github.com/firecrawl/pdf-inspector/blob/main/wasm/src/lib.rs) |
WASM binding layer: TypeScript definitions, option serialization, exported functions |
[src/lib.rs](https://github.com/firecrawl/pdf-inspector/blob/main/src/lib.rs) |
Core public API (process_pdf_mem_with_options) shared by CLI, Node.js, and WASM |
[src/detector.rs](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs) |
PDF type detection: TextBased, Scanned, Mixed, ImageBased classification |
[src/markdown/convert.rs](https://github.com/firecrawl/pdf-inspector/blob/main/src/markdown/convert.rs) |
Text‑to‑Markdown conversion with profile selection |
The WASM layer is a thin wrapper around this core library—the same Rust code powers the pdf2md CLI tool and native Node.js bindings.
Summary
- Initialize once: Call
init()asynchronously to load the WASM binary, then use synchronous API calls. - Choose your mode:
processPdffor full extraction,detectPdffor classification,extractTextfor plain text. - Control output: Use
options.pagesfor selective processing andoptions.profileto toggle between"fidelity"and"compact"Markdown. - Stay private: All processing happens client‑side with no network transmission of PDF data.
- Single codebase: The WASM module delegates to
pdf_inspector::process_pdf_mem_with_optionsand related functions from the core Rust library.
Frequently Asked Questions
How do I load the WASM binary in a bundler like Vite or webpack?
The @firecrawl/pdf-inspector-wasm package includes the .wasm file as a base64‑encoded or separate asset depending on your build tool. Call init() without arguments to use the default bundler integration, or pass a custom URL: init(binaryUrl). Check your bundler's WASM handling documentation for optimal chunking.
Can I use pdf‑inspector WebAssembly in a Web Worker?
Yes. Since init() is the only async function and all processing calls are synchronous, you can load and initialize the module in a dedicated worker, then process PDFs off the main thread. Pass Uint8Array data via postMessage or Transferable objects.
What PDF features trigger OCR requirements?
According to the detector implementation in [src/detector.rs](https://github.com/firecrawl/pdf-inspector/blob/main/src/detector.rs), pages are flagged for OCR when they contain no extractable text streams, have image‑only content, or show low text density relative to page area. The pagesNeedingOcr array in processPdf results identifies these specifically.
How does the "compact" profile differ from "fidelity"?
As implemented in [src/markdown/convert.rs](https://github.com/firecrawl/pdf-inspector/blob/main/src/markdown/convert.rs), "fidelity" preserves header hierarchies, lists, and tables with structural Markdown, while "compact" collapses formatting to minimize token count for LLM consumption—merging adjacent text and simplifying list markers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →