MD2PDF OnlineMD Converter
← Back to Blog

How to Use MarkItDown: Microsoft's Python Tool for Converting Anything to Markdown (2026 Tutorial)

Microsoft's markitdown is a small Python package with a big job: turn almost any file — PDF, Word, PowerPoint, Excel, images, audio, HTML — into clean Markdown. It's become one of the fastest-growing tools in the LLM/RAG ecosystem because Markdown is the format language models handle best.

This tutorial walks you through installing markitdown, converting your first files, using it inside Python scripts, and hooking it into common LLM workflows. No prior Python experience required — just a working pip.

If you'd rather compare markitdown against Pandoc before diving in, we wrote a side-by-side breakdown that clarifies which tool fits which direction.

What is markitdown, in one sentence?

Anything in, Markdown out. You give it a file (or a URL); it gives you a .md file that an LLM, static-site generator, or knowledge base can consume without further parsing.

Compared to older tools like pdftotext or docx2txt, markitdown preserves structure — headings stay headings, tables stay tables, lists stay lists — which is exactly what LLMs are trained to read.

Installation

markitdown runs on Python 3.10+. If you have Python installed, one command is all you need:

pip install markitdown

To verify:

markitdown --help

You should see a list of commands. If you get "command not found," your Python bin directory isn't on your PATH — either add it or use python -m markitdown instead.

Optional: install with extras

markitdown supports optional dependencies per file type. If you only care about a few formats, you can install just those:

# Only PDF and DOCX
pip install "markitdown[pdf,docx]"

# Everything (audio transcription, image OCR, etc.)
pip install "markitdown[all]"

Installing [all] will also pull in openai-whisper for audio, which is a large download — skip it unless you need speech-to-text.

Your First Conversion — Command Line

Once installed, converting a file is a one-liner:

markitdown quarterly-report.pdf > report.md

That's it. The Markdown is written to report.md. You can now open it in any editor, drop it into ChatGPT, or run it through MD2PDF Online to re-export as a styled PDF.

Convert other formats

The same command works for every supported input type:

# Word document
markitdown proposal.docx > proposal.md

# PowerPoint slides
markitdown pitch-deck.pptx > pitch.md

# Excel workbook
markitdown budget.xlsx > budget.md

# Image with text (OCR)
markitdown screenshot.png > screenshot.md

# Audio file (speech-to-text)
markitdown meeting.mp3 > meeting.md

# Web page
markitdown https://en.wikipedia.org/wiki/Markdown > wiki.md

# YouTube transcript
markitdown "https://youtu.be/dQw4w9WgXcQ" > transcript.md

Batch a whole folder

Shell globbing works, so you can convert an entire directory in one go:

for file in inbox/*.pdf; do
  markitdown "$file" > "output/$(basename "${file%.pdf}").md"
done

Or on Windows PowerShell:

Get-ChildItem inbox\*.pdf | ForEach-Object {
  markitdown $_.FullName > "output\$($_.BaseName).md"
}

Using markitdown in Python

The CLI is great for one-off jobs; for anything programmatic, use the Python API.

Basic example

from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("report.pdf")

print(result.text_content)   # the Markdown string

result is a DocumentConverterResult object with these fields:

  • text_content — the Markdown string
  • title — the extracted document title (if any)

Save to a file

from markitdown import MarkItDown
from pathlib import Path

md = MarkItDown()
result = md.convert("slides.pptx")

Path("slides.md").write_text(result.text_content, encoding="utf-8")

Convert a URL

result = md.convert("https://example.com/article")
print(result.text_content)

Convert bytes (useful for web uploads)

import io

with open("upload.docx", "rb") as f:
  buffer = io.BytesIO(f.read())

result = md.convert_stream(buffer, file_extension=".docx")

convert_stream is what you want inside a FastAPI or Flask endpoint that receives file uploads.

Feeding markitdown Output to an LLM

The most common reason people install markitdown is to prepare documents for an LLM. Here's a minimal RAG-style example using the OpenAI Python SDK:

from markitdown import MarkItDown
from openai import OpenAI

md = MarkItDown()
client = OpenAI()

# Step 1: Convert the source doc to Markdown
doc_md = md.convert("legal-contract.pdf").text_content

# Step 2: Ask the model a question about it
response = client.chat.completions.create(
  model="gpt-4o-mini",
  messages=[
    {"role": "system", "content": "You are a legal analyst. Answer using only the provided document."},
    {"role": "user", "content": f"Document:\n\n{doc_md}\n\nQuestion: What is the termination clause?"},
  ],
)

print(response.choices[0].message.content)

The same pattern works with Anthropic's Claude, Google's Gemini, or a local model via Ollama — just swap the SDK. What matters is that the model receives Markdown, not raw PDF text, so it can read headings and tables as structure rather than random newlines.

Chunking for vector databases

If you're building a RAG pipeline that indexes many documents into Pinecone/Weaviate/pgvector, chunk the Markdown at heading boundaries:

import re

def chunk_by_headings(markdown, max_chars=2000):
  sections = re.split(r"(?=^#+\s)", markdown, flags=re.MULTILINE)
  chunks, current = [], ""
  for section in sections:
    if len(current) + len(section) > max_chars and current:
      chunks.append(current)
      current = section
    else:
      current += section
  if current:
    chunks.append(current)
  return chunks

chunks = chunk_by_headings(md.convert("policy.pdf").text_content)

Heading-aligned chunks retrieve better than fixed-size splits because they preserve semantic boundaries.

Better PDF Extraction with Azure Document Intelligence

The default markitdown PDF reader is fine for most modern, text-based PDFs. For scanned PDFs or documents with complex tables, layered figures, and multi-column layouts, you can plug in Azure AI Document Intelligence:

from markitdown import MarkItDown

md = MarkItDown(
  docintel_endpoint="https://YOUR-RESOURCE.cognitiveservices.azure.com/",
)
result = md.convert("scanned-invoice.pdf")

Azure Document Intelligence is a paid API (billed per page), but the quality jump on messy PDFs is significant — tables reconstruct correctly, checkbox states are preserved, and OCR handles rotated pages.

If you don't have an Azure account and just need occasional OCR, an alternative is to run Tesseract first (tesseract input.pdf output pdf) and then feed the resulting text-layer PDF to markitdown for free.

Common Errors and Fixes

ModuleNotFoundError: No module named 'markitdown'

You installed markitdown in a different Python environment than the one you're running. Check with:

which python
which markitdown

If they point to different bins, activate the correct virtualenv or reinstall with python -m pip install markitdown.

Unsupported file format

markitdown identifies files by extension. If your file is report with no extension, rename it to report.pdf, or pass the extension explicitly when using convert_stream.

PDFs come out as one giant blob of text

This usually means the PDF has no text layer (it's a scan). Options:

  1. Use Azure Document Intelligence (best quality).
  2. Run OCR first with Tesseract or ocrmypdf.
  3. Try MD2PDF Online's PDF to Markdown tool, which handles scanned PDFs through its own OCR pipeline.

Audio transcription is extremely slow

markitdown[all] uses OpenAI Whisper locally, which is CPU-bound. For long files, either:

  • Install a GPU-enabled Whisper build,
  • Or pre-transcribe with a hosted API (Deepgram, AssemblyAI) and feed the transcript text to your pipeline directly.

When to Use markitdown vs. an Online Tool

markitdown is the right tool when you're building something programmatic — a RAG pipeline, an ingestion script, a batch job. It's overkill for one-off conversions.

For occasional conversions or when you don't want to touch Python:

Direction Recommended Tool
PDF → Markdown (one-off, in a browser) MD2PDF Online — PDF to Markdown
Markdown → PDF (one-off, in a browser) MD2PDF Online — Markdown to PDF
PDF → Markdown (bulk, scripted, LLM pipeline) markitdown
Markdown → PDF (bulk, templated, CI/CD) Pandoc

We break down all four in detail in the markitdown vs Pandoc comparison.

Bonus: A Full Ingestion Script

Here's a script you can drop into a project — it watches a folder, converts new files to Markdown, and writes them into a .md output directory. Useful for personal knowledge bases (Obsidian, Logseq) or as a first stage in a RAG ingestion job.

import time
from pathlib import Path
from markitdown import MarkItDown

INPUT = Path("inbox")
OUTPUT = Path("markdown")
OUTPUT.mkdir(exist_ok=True)

md = MarkItDown()
seen = set()

while True:
  for file in INPUT.iterdir():
    if file.name in seen or file.is_dir():
      continue
    try:
      result = md.convert(str(file))
      out_path = OUTPUT / (file.stem + ".md")
      out_path.write_text(result.text_content, encoding="utf-8")
      print(f"✓ {file.name}{out_path.name}")
      seen.add(file.name)
    except Exception as e:
      print(f"✗ {file.name}: {e}")
  time.sleep(5)

Drop a PDF, DOCX, or PPTX into inbox/, and a matching .md appears in markdown/ within seconds.

FAQ

Is markitdown free?

Yes. markitdown is MIT-licensed and works fully offline for all supported formats. The only paid piece is optional Azure Document Intelligence for premium PDF quality.

Does markitdown work on Windows?

Yes. Install Python 3.10+ from python.org, then pip install markitdown. Everything works identically across Windows, macOS, and Linux.

Can markitdown convert Markdown to PDF?

No — it only goes into Markdown. To go the other way, use MD2PDF Online (browser-based, no install) or Pandoc for a local toolchain.

How does markitdown compare to Unstructured, LlamaParse, or Docling?

They all target the same "docs → LLM-ready text" niche. markitdown is the simplest to install (one pip), works offline, and covers the widest input variety (audio, YouTube, ZIP). Unstructured and LlamaParse have stronger table extraction for enterprise use cases; Docling excels at scientific papers. For most personal and mid-sized projects, markitdown is enough.

Does markitdown preserve images?

Text embedded in images is extracted via OCR. The images themselves are not re-embedded in the Markdown output; if you need image passthrough, run a separate extraction step.

Wrapping Up

markitdown fills a very specific hole in the toolchain: "I have a pile of documents and I want them as clean Markdown, right now, without wiring up a Python stack for each format." If that's your problem, pip install markitdown will solve it in under a minute.

Once your content is in Markdown, you have options: feed it to an LLM, index it into a vector database, drop it into your notes app, or send it back out to PDF via MD2PDF Online. Markdown is the universal middle format — markitdown is what gets you there.


Next reads: