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) — Converts JsValue into WasmProcessOptions, gracefully handling undefined/null.
  • build_options (source line 86‑118) — Maps WasmProcessOptions to core PdfOptions, validating 1‑indexed page numbers and converting profile strings ("fidelity" or "compact") to the MarkdownProfile enum.

Processing Entry Point

The process_pdf function (source line 29‑40) orchestrates execution:

  1. Calls initialize() to install console_error_panic_hook for readable JavaScript stack traces (source line 25‑27).
  2. Builds PdfOptions with ProcessMode::Full.
  3. Measures timing via js_sys::Date::now().
  4. Delegates to pdf_inspector::process_pdf_mem_with_options (source line 35‑36).
  5. Wraps results in WasmPdfProcessResult and 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: processPdf for full extraction, detectPdf for classification, extractText for plain text.
  • Control output: Use options.pages for selective processing and options.profile to 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_options and 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →