Tools

MarkItDown: convert PDF, Word, Excel and images to Markdown for LLMs

TL;DR

MarkItDown turns PDFs, Office files, images, audio and HTML into Markdown that keeps headings and tables, a format LLMs read well and that saves tokens. With untrusted input, use the narrowest conversion function since it runs with the process's privileges.

Hand a Word, PowerPoint or Excel file to an LLM and you immediately hit problems: binary formats, tables, messy headings. Copy-paste loses structure; writing a parser for each file type takes effort. Microsoft's MarkItDown is a lightweight Python library that converts most common file types into Markdown, the format LLMs read best, keeping headings, lists, tables and links.

What does it support?

GroupFormats
OfficePDF, Word, PowerPoint, Excel
MediaImages (EXIF metadata, OCR), audio (metadata, speech transcription)
Web and dataHTML, CSV, JSON, XML, YouTube URLs, EPub
ArchivesZIP (iterates over contents)

Install and use

pip install 'markitdown[all]'          # or just [pdf, docx, pptx]

markitdown q3-report.pdf > q3-report.md
markitdown slides.pptx -o slides.md
from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("contract.docx")
print(result.text_content)   # Markdown ready to put in a prompt

It requires Python 3.10 or later. You can install dependency groups individually to stay lean. MarkItDown also supports plugins, such as an OCR plugin that uses a vision model to extract text from images embedded in PDF, Word, PowerPoint and Excel files.

Why Markdown?

  • LLMs saw a lot of Markdown in training, so they understand headings, tables and lists well.
  • Markdown is more compact than HTML or XML, saving tokens.
  • Preserved structure makes chunking for RAG along headings more natural.

Fitting it into a pipeline

  1. Convert files to Markdown with MarkItDown.
  2. Chunk by heading (#, ##).
  3. Embed and index, or put small documents straight into the prompt.
  4. Keep the intermediate Markdown for debugging wrong answers.

Risks and caveats

  • Runs with the current process's privileges: the README warns that MarkItDown accesses files and URLs with the process's privileges, like open() or requests.get(). With untrusted input, sanitise it and use the narrowest conversion function (e.g. convert_stream()); don't let users pass arbitrary paths or URLs.
  • Not for high-fidelity human-readable conversion: it's meant for machine analysis; complex layouts can be lost.
  • Scanned PDFs: without a text layer you need OCR; quality depends on the image.
  • Complex tables: merged cells and nested tables may be flattened incorrectly; test with real documents.
  • Sensitive data: plugins using a remote vision model send images outside.

How to apply it

  • Dev: Replace per-format parsing code with MarkItDown; write tests with a few hard sample files (merged tables, multi-column PDFs).
  • Tech Lead: Run conversions in an isolated environment when processing user uploads.
  • PM: A "chat with your documents" feature can be prototyped in a day with MarkItDown plus Claude.

Sources & references

  1. markitdown — Microsoft (GitHub)