Open Source
Anydoc: Turning Word, Excel and PDF into Markdown in Four Milliseconds
By DI Solutions
Developer


Anydoc is a Rust library that converts fourteen document formats into clean Markdown in single-digit milliseconds, with no LibreOffice, no Java runtime and no machine-learning models anywhere in the path. It ships bindings for Node, Python and WebAssembly, plus a command-line tool.
It solves the least glamorous problem in AI engineering: getting text out of the files clients actually send you.
Key takeaways
- Fourteen formats — the Word, PowerPoint and Excel families, OpenDocument, RTF, EPUB, CSV and PDF — all parse into one internal model, then serialise once. That is why the output is consistent regardless of what went in.
- Format detection reads the file's content, not its extension. A
.docxthat is secretly an RTF still converts. - No external binaries and no models means a container that is small and starts instantly.
- The Node bindings are non-blocking and the Python bindings release the GIL, so it is built for concurrent server use.
- The WebAssembly build converts files in the browser with no upload — a real privacy story, not a marketing one.
- The catch: local PDF handling is text-only. Scanned pages need opt-in hosted OCR, which sends the bytes off your machine.
Why is document conversion so painful?
Every AI product with an upload button hits the same wall. The client sends a folder. Inside it: forty Word documents from three different decades, a spreadsheet where the real data starts on row 14, a PowerPoint deck that is mostly text boxes, and a PDF that turns out to be photographs of paper.
The usual answer is a pile of libraries. One for Word, one for PDF, headless LibreOffice for the awkward ones, something else for spreadsheets. Each produces differently shaped output. Tables come out mangled in four distinct ways. One of them wants a Java runtime, so your container image gains half a gigabyte. Another downloads a model on first run, so your cold start doubles.
Then someone asks why the chatbot cannot answer a question, and the answer is that the paragraph it needed was inside a table your PDF extractor rendered as a single unbroken line of words.
This is the first mile of every retrieval pipeline, and it is where most of them quietly lose their quality.
How does Anydoc work?
The architectural decision that matters is that everything converges on one document model. Fourteen parsers, one internal representation, one Markdown serialiser.
- Detect by content. The file is sniffed by its signature rather than trusted by its extension. CSV is the exception — it has no signature, so it must be named.
- Parse into the shared model. Headings, lists, tables, footnotes and equations all become the same node types no matter which format they arrived in.
- Serialise once. One writer emits GitHub-Flavored Markdown, with equations as LaTeX and embedded assets extracted with their media types.
- Fail with a type. Errors are enumerated — unsupported, needs OCR, malformed, encrypted, resource limit, missing part — so your pipeline can route a scanned file to OCR and a password-protected file to a human, instead of logging one generic exception for both.
It also enforces fixed limits on decompression ratio and nesting depth, which is a quiet nod to the fact that Office formats are zip archives and a hostile upload is a real threat model.
What does using it look like?
Whichever language you are in, the API is one call. From the command line:
npx @firecrawl/anydoc slides.pptx -o slides.mdFrom Node:
const markdown = await toMarkdown('report.docx');From Python, with hosted OCR enabled for scanned pages:
markdown = anydoc.to_markdown("report.docx", ocr="hosted")Install is per-ecosystem: npm install @firecrawl/anydoc, pip install firecrawl-anydoc, or cargo add anydoc. There is a WebAssembly package for the browser and an agent skill so a coding agent can drive it directly.
How does it compare?
The project benchmarks itself against six competitors over a hundred real-world documents and reports the best overall score, and the only tool in the comparison that handled all fourteen formats. As always, that benchmark was designed by the project being benchmarked — but the format-coverage claim is checkable and the deployment-weight claim is self-evident.
| Aspect | Anydoc | MarkItDown | Docling |
|---|---|---|---|
| Runtime deps | None | Python stack | Python plus ML models |
| Speed | Milliseconds | Slower | Slowest — it is running inference |
| Scanned documents | Hosted OCR only | Limited | Strongest — this is its purpose |
| Runs in a browser | Yes, via WebAssembly | No | No |
| Language bindings | Rust, Node, Python, WASM, CLI | Python | Python |
Alternatives worth knowing
- Docling — if your corpus is genuinely scanned documents with complex layouts, the machine-learning approach earns its weight. Anydoc will send those pages to a hosted service; Docling reads them locally.
- Pandoc — a universal, extremely mature converter. One binary, decades of edge cases handled. Worth reaching for when your inputs are well-formed and you want something boring.
- MarkItDown — if your stack is already Python and throughput is not a constraint, the simplest thing that works may be the right thing.
- Unstructured — heavier, but it does chunking and element classification as well as extraction, which is sometimes the whole job.
Where this fits in a RAG pipeline
Retrieval quality is decided before a single embedding is computed. If your chunker receives a table flattened into one line, no amount of clever reranking recovers the rows.
Markdown is the useful intermediate because it keeps the structure that gives a chunk its meaning — a heading tells the chunker where a section starts, a table stays a table, a list stays a list. Chunk on headings, and each chunk arrives at your vector database already carrying its own context. The rest of that pipeline is covered in our guide to retrieval-augmented generation.
For crawled web sources rather than uploaded files, the equivalent step is a crawler that emits Markdown — Scrapling ships a spider that does exactly that.
Limitations to plan around
- Scanned PDFs leave your machine. Hosted OCR is opt-in, but if your corpus is scanned contracts under an NDA, that is a conversation with the client before it is a configuration flag.
- Encrypted files will not convert. Route them to a human rather than retrying.
- CSV must be named explicitly, because content sniffing cannot identify it.
- The resource limits are fixed. They protect you from zip bombs; they will also reject a legitimately enormous document.
- It is very new. Pin the version, and keep a fallback converter in the pipeline for the formats you cannot afford to drop.
Conclusion
Anydoc is unglamorous in the best way. It does one job, it does it fast, and it does not drag a Java runtime or a model download into your container to do it.
For anyone building document ingest — and in 2026 that is nearly everyone building an AI feature — it removes a whole category of deployment weight. Just decide the OCR question before you promise anything about scanned files.
Building something that eats your clients' documents?
DI Solutions builds document ingest and retrieval pipelines end to end — extraction, chunking, embeddings, and a front end people will actually use. Hire our AI engineers and skip the six weeks of format wrangling.
Reference links
Frequently Asked Questions (FAQs)
What is Anydoc?
Anydoc is an open-source Rust library that converts fourteen document formats — Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV and PDF — into GitHub-Flavored Markdown. It ships bindings for Node, Python and WebAssembly, plus a command-line tool.
How fast is Anydoc?
The project reports a median conversion of 4.4 milliseconds and states that conversions complete in under five milliseconds. That speed comes from having no external binaries and no machine-learning models in the path — it is parsing, not inference.
Does Anydoc need LibreOffice or Java installed?
No, and that is the point. It has no external dependencies and downloads no models, so a container image needs nothing beyond the library itself. That removes the usual heavyweight install step from a document ingest service.
Can Anydoc read scanned PDFs?
Only through opt-in hosted OCR. The local path handles text PDFs. Scanned pages are routed to Firecrawl's hosted parse service, which means those bytes leave your machine — a decision worth making deliberately on client documents.
Can Anydoc run in the browser?
Yes. There is a WebAssembly build, so a page can convert a file locally with no upload and no server. That makes a genuinely private 'convert your document' tool possible, which is unusual for this category.
How does Anydoc compare to MarkItDown and Docling?
MarkItDown is Python-first and broad but slower. Docling uses machine-learning layout models, which makes it stronger on complex scanned layouts and far heavier to deploy. Anydoc trades that layout sophistication for speed, zero dependencies and multi-language bindings.
Why convert documents to Markdown at all?
Because retrieval pipelines and language models work on text, and Markdown preserves the structure — headings, lists, tables — that gives a chunk its meaning. Converting to plain text loses that structure; leaving documents in their native formats means every downstream step has to understand fourteen file formats.




