anydoc: Convert Office Docs to Clean Markdown at Sub-5ms Speeds

⬅️ Back to Tools

anydoc

What it isA Rust library that turns 14 office/ebook formats into clean GitHub-Flavored Markdown
PlatformmacOS, Linux, Windows (CLI, Python, Node.js, browser via WASM)
PriceFree, open source (MIT)
Linkgithub.com/firecrawl/anydoc

Every document pipeline ends the same way: whatever format goes in, you want clean Markdown out. I’ve stitched together pandoc scripts, LibreOffice headless calls, and Python soup scrapers to get there, and each one broke on some format or other. anydoc from Firecrawl is the closest I’ve found to a single tool that just does the whole job.

It converts Word (.doc/.docx/.docm), PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV, and PDF into one consistent GitHub-Flavored Markdown output. Pure Rust, no ML models, no cloud calls. Median conversion is under 5 milliseconds per document.

  1. One output for every format. Every parser funnels into a shared document model and a single Markdown serializer, so tables, escaping, heading anchors, and footnotes behave identically whether the input is a 2003 .doc or a fresh .pptx. I converted a docx with a table, blockquote, and nested list and got back clean GFM with the table intact, no hand-fixing needed.

  2. It is genuinely fast. The project benchmarks against six other converters on 100 real documents across 14 formats: 4.4ms median versus LibreOffice at 1129ms, pandoc at 102ms, markitdown at 135ms. That is not a marginal win, it is two to three orders of magnitude. For batch jobs on thousands of files the difference is hours.

  3. Format detection reads the bytes, not the filename. It checks the PDF header, RTF open group, OLE stream names, and ZIP mimetype, so a mislabeled file still converts correctly. The one exception: CSV has no in-content marker, so you pass the format name explicitly or rely on the extension.

  4. Bindings everywhere, and they stay out of the way. CLI via npx @firecrawl/anydoc, Python via pip install firecrawl-anydoc, plus Node.js and WebAssembly for the browser. The demo page runs the whole library as WASM so files never leave your machine. Node runs on the libuv thread pool, Python releases the GIL, so neither blocks your app.

  5. The honest limitations. Scanned PDFs need OCR, which anydoc does not do; you would feed those to Firecrawl’s hosted Parse instead. And the PDF path is the weakest: my test PDF came out with bold/italic runs glued together (this is aboldtest), because it routes through pdf-inspector rather than the shared document model. Office formats are the strong suit, text PDFs work but are rougher.

  6. It ships as an agent skill. npx skills add firecrawl/anydoc and your coding agent can read any document it runs into. That is the detail that makes this more than a library: it is designed for the LLM-pipeline use case end to end.

Worth your time if: you build RAG pipelines, batch-convert mixed office files, or want your coding agent to read docs without a cloud API call.

Install & first run

The fastest path is the CLI. First run downloads the prebuilt binary, later runs are near-instant:

npx @firecrawl/anydoc report.docx          # Markdown to stdout
npx @firecrawl/anydoc slides.pptx -o slides.md  # or to a file

CSV needs the format named, since the bytes carry no marker:

npx @firecrawl/anydoc - --format csv < data.csv

For scripts, the Python binding matches the CLI:

pip install firecrawl-anydoc
import anydoc

markdown = anydoc.to_markdown("report.docx")
markdown = anydoc.to_markdown_bytes(data, "csv")
document = anydoc.to_document(data)

The to_document variant returns the document model with embedded assets (images as alt text in Markdown, raw bytes tagged by media type on the model). See the GitHub README for the Node, WASM, and Rust APIs.

Related TMFNK Content

Crepi il lupo!