Using pdf-inspector in the Browser (WebAssembly) - Local Parsing
API ReferenceWebAssembly
pdf-inspector compiles to WebAssembly and runs entirely in the browser — its most distinctive capability: parsing happens locally in the user's browser; files never leave the device. The demo on this site is built exactly this way.
Install
npm install @firecrawl/pdf-inspector-wasmWorks in pure-frontend projects; no backend required.
Core APIs
import init, { processPdf, detectPdf, classifyPdf, extractText } from '@firecrawl/pdf-inspector-wasm'
// 1. Initialize wasm once at startup
await init()
const bytes = new Uint8Array(await file.arrayBuffer())
// 2. All-in-one: classification + Markdown
const result = processPdf(bytes)
console.log(result.pdfType) // "TextBased" | "Scanned" | "Mixed" | "ImageBased"
console.log(result.markdown)
// 3. Classification only, no extraction
const info = detectPdf(bytes)
// 4. Lightweight classification (same shape as the native Node API)
console.log(classifyPdf(bytes).pagesNeedingOcr)Pass options when needed:
const result = processPdf(bytes, {
pages: [1, 3, 5], // selected pages only
profile: 'compact', // token-saving output
includePageMarkers: true, // add page markers
})A complete drop-in-and-parse example
<input type="file" id="pdf" accept=".pdf,application/pdf" />
<pre id="out"></pre>import init, { processPdf } from '@firecrawl/pdf-inspector-wasm'
await init()
document.getElementById('pdf').addEventListener('change', async (e) => {
const file = e.target.files[0]
if (!file) return
const bytes = new Uint8Array(await file.arrayBuffer())
try {
const result = processPdf(bytes)
document.getElementById('out').textContent =
`[${result.pdfType}]\n${result.markdown}`
}
catch (err) {
document.getElementById('out').textContent = `Parse failed: ${err}`
}
})The privacy pitch: why files never leave the device
- Parsing logic is Rust compiled to wasm, running inside the browser sandbox
- No upload requests, no backend relay —
file.arrayBuffer()stays in memory - Ideal for sensitive documents: contracts, medical records, financial data
Browser behavior worth knowing
- Single-threaded build: no COOP/COEP cross-origin isolation headers needed — any static host works
- CJK out of the box: CMaps are embedded; CJK font decoding never touches a filesystem
- Synchronous execution: extraction blocks after
init(); call it from a Web Worker for large documents - No OCR: image-only PDFs need a separate OCR step — the build reports a clear type verdict instead of pretending
Performance & size
- The wasm binary is a few MB (smaller gzipped); first load takes a moment, then it's cached. Lazy-load
initto keep it off the critical path. - Parsing speed is close to native — same Rust core, wasm sandbox
- The demo on our home page uses it: drop a PDF, get the verdict and Markdown instantly
Tips
- Call
await init()only once and reuse the instance — don't reinitialize per parse - In Vite projects add the package to
optimizeDeps.excludeso wasm assets aren't mangled by dev pre-bundling (this site does exactly that) - Watch memory for very large documents — wasm holds roughly file-sized buffers