anydoc in the Browser (WebAssembly) - Local Conversion
API ReferenceWebAssembly
anydoc compiles to WebAssembly and runs in the browser — which makes it special: conversion happens entirely on the user's device, and files never leave it. The converter on this site's home page is exactly this approach.
Install
npm install @firecrawl/anydoc-wasmWorks in any frontend project — no backend required.
Basic usage
import init, { toMarkdownBytes, toDocument } from '@firecrawl/anydoc-wasm'
// 1. Initialize the wasm (once, at app startup)
await init()
// 2. Convert from a File object
const file = inputElement.files[0]
const bytes = new Uint8Array(await file.arrayBuffer())
const markdown = toMarkdownBytes(bytes)
// 3. Stop at the document model (keep embedded assets)
const document = toDocument(bytes)A complete upload-and-convert example
<input type="file" id="doc" accept=".docx,.pptx,.xlsx,.pdf,.doc,.ppt,.xls,.odt,.ods,.odp,.rtf,.epub,.csv" />
<pre id="out"></pre>import init, { toMarkdownBytes } from '@firecrawl/anydoc-wasm'
await init()
document.getElementById('doc').addEventListener('change', async (e) => {
const file = e.target.files[0]
if (!file) return
const bytes = new Uint8Array(await file.arrayBuffer())
try {
const md = toMarkdownBytes(bytes)
document.getElementById('out').textContent = md
}
catch (err) {
document.getElementById('out').textContent = `Conversion failed: ${err.code || err}`
}
})The privacy pitch: why files never leave the device
- Conversion logic is Rust compiled to wasm, running inside the browser sandbox
- No upload request, no backend relay — after
file.arrayBuffer(), the bytes live in memory - Perfect for sensitive documents (contracts, medical records, financial data) that need in-browser conversion
Performance & size
- The wasm binary is a few MB (less gzipped); the first load costs a moment, then it's resident
- Conversion speed is close to native — same Rust core, running in the wasm sandbox
- This site's converter is built on it: drag a file in, Markdown out in milliseconds
Tips
- Call
await init()once and reuse the instance — don't re-initialize per conversion - Very large files (hundreds of MB) will consume memory proportional to the file; keep that in mind
- Scanned PDFs still return
unsupported— there's no OCR capability in the browser build, and that's a deliberate boundary