PDFtoMD
DevelopersDoclingIBMPython

Docling Tutorial: Convert PDF to Markdown with IBM Open Source Toolkit

Docling is IBM open source document converter, strong on complex tables and built in LangChain and LlamaIndex loaders. A practical tutorial with install steps, working code, and the tradeoffs versus MinerU and Marker.

8 min readBy Rafael Abellan

Docling is an open source document conversion toolkit from IBM Research. It reads PDFs, DOCX, PPTX, HTML, and images, and turns them into a structured document model that you can export to clean Markdown. What sets it apart from most converters is how seriously it treats layout: it runs dedicated models for page layout and table structure, so complex tables, multi column pages, and reading order survive the trip to Markdown far better than a naive text extractor would allow.

For anyone building retrieval augmented generation (RAG) systems, Docling has one more thing going for it. It ships with first party loaders for both LangChain and LlamaIndex, so the same tool that parses your PDF can hand structured chunks straight to your vector store. This tutorial walks through installing Docling, converting a PDF to Markdown, handling tables and scanned documents, wiring it into a RAG pipeline, and deciding when it is the right tool versus MinerU or Marker.

What Docling Is Good At

Docling started life inside IBM Research and was open sourced under a permissive MIT license. It has since become one of the most widely adopted document parsers in the Python ecosystem, and it is the parser behind several enterprise document AI stacks. The design goal is fidelity: instead of dumping a flat stream of text, Docling builds a rich document representation with sections, tables, figures, lists, and captions, then serializes that structure to Markdown, JSON, or HTML.

The headline strengths are worth calling out before you install anything:

  • Table structure recognition: Docling uses a purpose built model (TableFormer) to reconstruct cell boundaries, merged cells, and headers. This is where most converters fall apart, and it is Docling's single biggest advantage.
  • Reading order and layout: A layout model figures out the correct sequence of blocks on multi column pages, so your Markdown does not interleave columns.
  • OCR for scanned PDFs: Optional OCR engines (EasyOCR, Tesseract, and others) handle image only pages.
  • Framework loaders: Native LangChain and LlamaIndex integrations mean less glue code when you are building RAG.
  • Local and private: Everything runs on your own machine. No documents leave your network, which matters for legal, medical, and financial content.

Installing Docling

Docling is a Python package. It targets Python 3.9 and newer, and it works on macOS, Linux, and Windows. Create a virtual environment first so its model dependencies do not collide with the rest of your system, then install from PyPI:

python -m venv venv
source venv/bin/activate       # on Windows: venv\Scripts\activate
pip install docling

The first install pulls in PyTorch and a set of pretrained models for layout and table recognition. On the first run, Docling downloads the model weights and caches them locally, so the very first conversion is slower than every one after it. If you work behind a firewall, pre download the models on a machine with internet access and copy the cache across, or point Docling at a local artifacts path.

A CPU only machine is enough to get started. If you have an NVIDIA GPU, PyTorch will use it automatically and large documents convert several times faster. For scanned PDFs you will also want an OCR engine. EasyOCR is bundled by default, so you do not need extra steps for basic OCR.

Your First Conversion

The core API is deliberately small. You create a DocumentConverter, point it at a file or URL, and export the result. Here is the minimal script that turns a PDF into a Markdown file:

from docling.document_converter import DocumentConverter

converter = DocumentConverter()
result = converter.convert("report.pdf")

markdown = result.document.export_to_markdown()

with open("report.md", "w", encoding="utf-8") as f:
    f.write(markdown)

print("Done. Wrote report.md")

That is the whole flow. The result.document object is the structured representation, and export_to_markdown() serializes it. You can also call export_to_dict() to get JSON that preserves the full hierarchy, which is handy when you want to store the layout and generate Markdown later. The converter accepts a local path, a URL, or a stream, so you can convert a document straight from the web without downloading it first.

Do not want to manage Python models? Convert your PDF to clean Markdown in your browser, free.

Handling Tables Well

Tables are the reason many teams choose Docling. By default table structure recognition is on, but you can tune how aggressive it is. The accurate mode spends more compute to align cells precisely, which pays off on dense financial statements and data sheets:

from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions, TableFormerMode

pipeline_options = PdfPipelineOptions()
pipeline_options.do_table_structure = True
pipeline_options.table_structure_options.mode = TableFormerMode.ACCURATE

converter = DocumentConverter(
    format_options={
        InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
    }
)

result = converter.convert("financials.pdf")
print(result.document.export_to_markdown())

The output is a proper Markdown table with aligned pipes and a header row, not a jumble of numbers on separate lines. If your documents are mostly tabular, this alone can save hours of manual cleanup. For a deeper look at getting tables right across tools, see our guide on how to convert PDF tables to clean Markdown.

Converting Scanned PDFs with OCR

If your PDF is a scan or an image only export, there is no embedded text layer to extract. Docling can run OCR on those pages. Turn it on through the pipeline options:

from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.datamodel.base_models import InputFormat
from docling.datamodel.pipeline_options import PdfPipelineOptions

pipeline_options = PdfPipelineOptions()
pipeline_options.do_ocr = True

converter = DocumentConverter(
    format_options={
        InputFormat.PDF: PdfFormatOption(pipeline_options=pipeline_options)
    }
)

result = converter.convert("scanned-contract.pdf")
print(result.document.export_to_markdown())

OCR is slower than plain text extraction because every page becomes an image recognition task, so only enable it when you need it. Docling can also auto detect which pages need OCR and only run it on those, which keeps mixed documents fast. If OCR quality on your language or font is poor with the default engine, you can swap in Tesseract or another supported backend through the same options object.

Batch Converting a Folder

Most real work is not one file, it is a directory of them. Docling reuses the loaded models across calls, so converting a folder is just a loop. Building the converter once outside the loop keeps the models warm:

from pathlib import Path
from docling.document_converter import DocumentConverter

converter = DocumentConverter()
in_dir = Path("pdfs")
out_dir = Path("markdown")
out_dir.mkdir(exist_ok=True)

for pdf_path in in_dir.glob("*.pdf"):
    result = converter.convert(str(pdf_path))
    md = result.document.export_to_markdown()
    out_file = out_dir / (pdf_path.stem + ".md")
    out_file.write_text(md, encoding="utf-8")
    print("Converted", pdf_path.name)

For very large batches, wrap the conversion in a try and except block so one corrupt file does not stop the run, and log the failures to review later. Docling also exposes a command line interface, so you can run docling report.pdf from a shell script if you prefer not to write Python at all.

Docling in a RAG Pipeline

This is where Docling really shines. Because it produces structured output, it can chunk documents in a way that respects headings and tables instead of blindly splitting every N characters. The result is cleaner chunks, and cleaner chunks mean better retrieval. If RAG is new to you, start with our overview of how to build better RAG pipelines with clean Markdown.

For LangChain, Docling ships a document loader. Install the integration and load a PDF as Markdown ready documents in a few lines:

# pip install langchain-docling

from langchain_docling import DoclingLoader

loader = DoclingLoader(file_path="report.pdf")
docs = loader.load()

for d in docs[:3]:
    print(d.page_content[:200])

The loader returns LangChain Document objects with Markdown content and metadata, ready to pass to your text splitter, embedder, and vector store. LlamaIndex has an equivalent reader that plugs into its ingestion pipeline the same way. If you already work in these frameworks, this is a much shorter path than converting to Markdown first and re parsing it. For the full picture on both frameworks, read our guide to PDF to Markdown for LangChain and LlamaIndex, and browse the use cases where clean Markdown makes the biggest difference.

Docling versus MinerU and Marker

Docling is not the only strong open source converter, and the right choice depends on your documents. Here is an honest comparison of the three most common Python options.

ToolBest atSpeedRAG integrations
DoclingComplex tables, mixed layouts, enterprise docsModerateNative LangChain and LlamaIndex
MinerUScientific papers, LaTeX equationsModerate to slowCommunity integrations
MarkerSpeed on clean, text based PDFsFastCommunity integrations

Pick Docling when your documents are table heavy, when layout fidelity matters, or when you want the shortest path into a LangChain or LlamaIndex pipeline. Pick MinerU when you are converting scientific papers full of equations and want LaTeX preserved; our MinerU tutorial covers that case in detail. Pick Marker when raw throughput on clean PDFs is your priority and your tables are simple. Many teams end up running two of these: Docling for the hard documents and a faster tool for the easy bulk.

Common Gotchas

  • The first run is slow: Model downloads and warm up happen once. Benchmark on the second run, not the first.
  • OCR is opt in: If a scanned PDF comes out empty, you forgot to set do_ocr = True.
  • Memory on huge files: Very large PDFs can use a lot of RAM. Convert page ranges or split the file if you hit limits.
  • Accurate table mode costs time: Only switch to accurate mode for documents that actually need it.
  • Images are referenced, not embedded: Figures come through as references. Decide whether you need to export the image files alongside your Markdown.

Frequently Asked Questions

Is Docling free to use?

Yes. Docling is open source under the MIT license, so it is free for personal and commercial use. There are no API keys or usage fees because everything runs locally on your own hardware. Your only cost is the compute you provide.

Does Docling need a GPU?

No. Docling runs on a CPU only machine, which is fine for occasional conversions and small batches. A GPU speeds up layout and table models significantly, so if you convert thousands of pages a day, a GPU is a worthwhile upgrade rather than a requirement.

How well does Docling handle tables?

Table handling is Docling's strongest feature. Its TableFormer model reconstructs cell structure, merged cells, and headers, which is exactly where simpler converters produce garbled output. For dense financial and data tables, it is among the best open source options available.

Can Docling convert scanned documents?

Yes, with OCR enabled. Set do_ocr = True in the pipeline options and Docling will run OCR on image based pages. It can auto detect which pages need OCR so you do not pay the cost on pages that already have a text layer.

What is the difference between Docling and a hosted converter?

Docling is a library you install, configure, and maintain, which gives you full control and privacy at the cost of setup and compute. A hosted converter like PDFtoMD does the work in your browser with nothing to install. If you want a quick, clean conversion without touching Python, the hosted route is faster. If you need a repeatable local pipeline, Docling is the better fit.

The Takeaway

Docling is one of the most capable open source PDF to Markdown converters you can run today, and it earns that reputation on table quality, layout fidelity, and its native RAG integrations. If you are building a document pipeline in Python and your content is complex, it belongs on your shortlist alongside MinerU and Marker. Install it, run a few of your own hardest documents through it, and compare the Markdown against what you have now.

And when you just need one PDF turned into clean Markdown without setting up a Python environment, PDFtoMD converts it in your browser in seconds. The free tier gives you 3 conversions a month with no credit card, which is enough to check whether hosted conversion fits your workflow before you commit to running your own toolkit.

Rafael Abellan

About the author

Rafael Abellan

Founder, PDFtoMD

Rafael Abellan is the founder of Agência Triva and ships independent side projects in parallel. PDFtoMD came out of a personal frustration: he kept burning through Claude AI's token limit by uploading long PDFs, then losing hours waiting for the cap to reset. He built the tool to fix his own workflow, and now uses it every day.

Ready to convert your PDFs to Markdown?

Free account · 3 conversions/month · No credit card required