The Problem: Document Processing for LLMs

Large Language Models excel at understanding text, but they struggle with binary document formats. Before you can feed a Word document, PowerPoint presentation, Excel spreadsheet, or PDF into an LLM pipeline, you need to convert it to clean, structured text. Traditional conversion tools are often slow, produce messy output, or require complex setup with multiple dependencies.

Firecrawl’s anydoc, released August 3, 2026, solves this with a single function call that converts common office formats to clean Markdown in single-digit milliseconds. Built in Rust with Python and Node.js bindings, it’s designed specifically for LLM workflows [S1].

Under the Hood: Rust Powered

anydoc’s core is written in Rust, chosen for its memory safety, speed, and excellent FFI (Foreign Function Interface) capabilities [S1]. The Rust core parses the binary structure of each format and emits a structured intermediate representation (IR). This IR is then rendered to GitHub-flavored Markdown.

For each format, anydoc uses specialized parsers:

  • Word (.docx): Uses the zip-based Open XML format, parsing the document.xml and related parts directly.
  • Excel (.xlsx): Parses the shared strings table and sheet data with streaming to handle large sheets efficiently.
  • PowerPoint (.pptx): Extracts text from shape.xml and preserves slide order and hierarchy.
  • PDF: Uses poppler via Rust bindings for text-based PDFs; falls back to Tesseract OCR for scanned documents.
  • CSV: Streaming parsing with automatic dialect detection.

The Rust core is exposed to Python via PyO3, creating a Python extension that feels native. Node.js bindings use neon. This means the conversion happens at near-native speed with no Python-level loops over large data structures [S1].

Because the core is Rust, anydoc benefits from zero-cost abstractions and predictable performance. The single-digit millisecond times come from avoiding unnecessary allocations and using memory-mapped file I/O where possible.

How It Works: One Function Call

anydoc is a Rust-powered library that provides bindings for Python, Node.js, and can be used as a CLI tool. The Python interface is particularly simple:

“`python from firecrawl_anydoc import anydoc

Convert any supported format to Markdown

markdown_text = anydoc.convert(“report.docx”) markdown_text = anydoc.convert(“presentation.pptx”) markdown_text = anydoc.convert(“data.xlsx”) markdown_text = anydoc.convert(“document.pdf”) “`

Each conversion takes single-digit milliseconds on modern hardware [S1]. The library preserves document structure where possible — headings become Markdown headers, lists become Markdown lists, tables become Markdown tables — while stripping out unnecessary formatting and binary cruft.

Supported Formats

anydoc handles the most common office and document formats [S1]:

  • Word: .doc, .docx
  • PowerPoint: .ppt, .pptx
  • Excel: .xls, .xlsx
  • PDF: .pdf (with OCR fallback for scanned documents)
  • OpenDocument: .odt, .ods, .odp
  • EPUB: .epub
  • CSV: .csv
  • RTF: .rtf

The output is clean GitHub-flavored Markdown that LLMs can process efficiently. Tables maintain their structure, lists retain hierarchy, and heading levels are preserved.

Getting Started

Installation

Install the Python package with pip [S1][S2]:

bash pip install firecrawl-anydoc

The package includes the Rust binary and Python bindings [S2]. No separate Rust installation is needed [S1].

Basic Usage

“`python from firecrawl_anydoc import anydoc

Simple conversion

markdown = anydoc.convert(“financial_report.xlsx”) print(markdown)

Convert and save to file

with open(“report.md”, “w”) as f: f.write(anydoc.convert(“research_paper.pdf”))

Convert bytes (useful for web applications)

with open(“document.docx”, “rb”) as f: file_bytes = f.read() markdown = anydoc.convert_bytes(file_bytes, “.docx”) “`

Advanced Options

anydoc provides options for fine-tuning the conversion [S1]:

“`python

Preserve comments in Excel files

markdown = anydoc.convert(“spreadsheet.xlsx”, {“preserve_comments”: True})

Extract images as base64

markdown = anydoc.convert(“presentation.pptx”, {“extract_images”: True})

Set OCR language for PDFs

markdown = anydoc.convert(“scanned.pdf”, {“ocr_lang”: “eng+fra”})

Convert specific sheets or slides

markdown = anydoc.convert(“workbook.xlsx”, {“sheet_names”: [“Q1”, “Q2”]}) markdown = anydoc.convert(“deck.pptx”, {“slide_range”: [1, 5]}) “`

Performance and Quality

Speed

Conversions complete in single-digit milliseconds for typical documents [S1]:

  • Word documents (10-50 pages): 2-8 ms
  • Excel spreadsheets (multiple sheets): 3-10 ms
  • PowerPoint presentations: 4-12 ms
  • PDFs (text-based): 5-15 ms
  • Scanned PDFs (with OCR): 100-500 ms depending on page count

Output Quality

The Markdown output preserves semantic structure:

  • Document headings → Markdown headers (#, ##, ###)
  • Bullet and numbered lists → Markdown lists (-, 1.)
  • Tables → GitHub-flavored Markdown tables
  • Code blocks → fenced code blocks with language hints
  • Hyperlinks → standard Markdown links
  • Emphasis (bold/italic) → bold and italic

Complex elements like SmartArt, equations, and macros are either converted to appropriate Markdown representations or noted in comments.

Real-World Usage Examples

Here are practical examples of how anydoc fits into LLM workflows [S1]:

RAG Pipeline Preprocessingpython def process_uploaded_file(file_path): # Convert to Markdown for embedding markdown = anydoc.convert(file_path) chunks = split_into_chunks(markdown) # Your chunking function embeddings = embed_model.encode(chunks) vector_store.add(embeddings, chunks) return len(chunks)

Document Q&A Bot When a user uploads a document, convert it immediately: “python @app.route('/upload', methods=['POST']) def upload_document(): file = request.files['doc'] file_bytes = file.read() markdown = anydoc.convert_bytes(file_bytes, file.filename) # Now feed markdown to your LLM for Q&A answer = llm.ask(markdown, user_question) return jsonify({"answer": answer})

Knowledge Base Sync Keep your vector store updated with the latest documents: “python def sync_knowledge_base(): for doc_path in scan_directory("/company/docs"): markdown = anydoc.convert(doc_path) update_vector_store(doc_path, markdown)

These patterns show how anydoc eliminates the document processing bottleneck in LLM applications, making it feasible to process hundreds of documents per second in a production system.

This makes anydoc ideal for high-throughput LLM applications where document processing speed is critical.

Limitations to Know

Limitations to Know

PDF OCR Dependency. For scanned PDFs, anydoc uses Tesseract OCR as a fallback. You need to have Tesseract installed and language data available for OCR to work [S1]. Pure text PDFs convert without external dependencies.

Complex Formatting. Some advanced Word/PowerPoint features like complex animations, macros, or embedded objects may not convert perfectly. The library focuses on preserving content structure over pixel-perfect layout.

File Size Limits. While there’s no hard limit, extremely large files (100MB+) may consume significant memory during conversion. For very large documents, consider splitting them first.

No Format Preservation. The output is Markdown, not a format-specific representation. If you need to round-trip back to the original format, you’ll need different tools.

Verdict and Conclusion

Score: 5/5 — Do Not Miss. For anyone building LLM pipelines that need to process office documents, anydoc is essential. It’s fast (single-digit ms), simple (one function call), high-quality (clean structured Markdown), and broad in format support.

Best for: Developers building LLM applications that need to ingest office documents — RAG pipelines, document summarization tools, knowledge base builders, or any application that lets users upload files for AI processing.

Skip if: You only need to process plain text files, or you require format-preserving conversion back to the original binary format.

Evolve this: Try integrating anydoc into a document upload endpoint for your LLM chatbot, or use it to preprocess your company’s internal wiki exports before feeding them into a retrieval system.

Sources

  1. [S1] firecrawl/anydoc GitHub repository — GitHub (2026-08-03)
  2. [S2] firecrawl-anydoc PyPI package — PyPI (2026-08-03)
  3. [S3] @firecrawl/anydoc npm package — npm (2026-08-03)