4 min read

Docling: Documents to Clean Markdown and JSON (GitHub, Scanned)

Converts PDFs, Office files, HTML and more into clean Markdown or JSON, with tables and reading order intact.

Docling logo
✅
Scan: safe. Nothing to warn about. Every hit is documentation or test data, the LaTeX renderer keeps shell escape off by default, and the known advisories sit in docs and example tooling. Scanned Sep 25, 2026; the full report is below.

Docling reads the documents you actually have, PDFs above all, and turns them into structure a language model can use. Its PDF pipeline runs layout analysis, reading-order detection, table-structure recognition and OCR with its own small models, then exports Markdown, HTML or a lossless JSON format called DoclingDocument. The same converter handles DOCX, PPTX, XLSX, HTML, EPUB, email, LaTeX and images, and even audio and video through speech recognition, so one call covers a messy folder.

It earns its place as the ingestion step most retrieval pipelines need and few get right: tables come out as tables, and multi-column pages come out in reading order. It started at IBM Research Zurich, is now hosted by the LF AI & Data Foundation, and is MIT-licensed. It runs locally, which matters for sensitive files, and plugs into LangChain, LlamaIndex, CrewAI and Haystack, with an MCP server and an HTTP service (docling-serve) for everything else.

Who it is for

Developers building retrieval or document-processing pipelines, data teams pulling tables out of reports, and anyone who needs PDFs converted to Markdown on their own hardware rather than through a cloud API.

Getting started

1. Install (Python 3.10 or later; macOS, Linux and Windows)

pip install docling

2. Convert a document; the Markdown lands in the current directory

docling https://arxiv.org/pdf/2206.01062

3. Or use the GraniteDocling vision-language model instead of the standard pipeline

docling --pipeline vlm --vlm-model granite_docling https://arxiv.org/pdf/2206.01062

Safety scan

We cloned docling-project/docling at commit 2d5c590 on Sep 25, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • One secret hit, and it is a placeholder: docling/datamodel/service/sources.py documents a Google service-account field whose example value is a PEM header around the letters MIIEv and an ellipsis. No self-decoding code. The two bare-IP URLs are test fixtures (93.184.216.34, the old example.com address, and 8.8.8.8).
  • Two curl | sh hits. The LaTeX backend's TikZ renderer logs Tectonic's install one-liner as advice when Tectonic is missing and never runs it; that renderer is opt-in, and its shell-escape option defaults to off "for safer rendering of untrusted LaTeX". The other is a uv install line in an example notebook.
  • One binary: tests/data/epub/sources/epub_purvis_poetry.epub, flagged as a JAR because an EPUB is a ZIP archive underneath. It is a test book.
  • Five known advisories in uv.lock across 402 packages, none critical. The high one is pymdown-extensions, used only to build the documentation site; datasets sits in the examples group and setuptools is build tooling. The one in runtime code is a low-severity torch.jit.script issue in PyTorch.
  • 13 workflows. Two use pull_request_target: the DCO advisor only reads check results through the API, and the fast-checks job keeps its working tree on the trusted base commit and only reads the pull request's files. 9 of 15 third-party actions are pinned to a commit. Security policy, contributing guide and code of conduct present; no Dependabot or CodeQL.

What the scanner counted

CheckResult
Secrets1 candidate found and read; see the notes above.
Suspicious code2 pattern hits found and read; every one is listed under the raw findings.
Install-time codeNone: nothing runs at install beyond the package manager itself.
Committed binaries1 executable or compiled object committed; listed under the raw findings.
CI workflows13 workflows. 2 use pull_request_target, none check out the pull request head. 6 of 15 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often arxiv.org, github.com, colab.research.google.com, docling-project.github.io. 2 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities5 advisories across 402 pinned packages: 0 critical, 1 high, 2 moderate, 1 low, 1 unrated. uv.lock: 402 packages, 5 advisories.
Project hygieneHas security policy, licence file, contributing guide. Missing automated dependency updates, CodeQL.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Secret candidates (1, redacted)
WhereRuleMatch
docling/datamodel/service/sources.py:183private-key-----B…--- (27 chars)
Pattern hits (2)
WhereRuleMatch
docling/backend/latex/engines/tectonic.py:89download-piped-to-shell"curl --proto '=https' --tlsv1.2 -fsSL https://drop-sh.fullyjustified.net | sh"
docs/examples/rag_opensearch.ipynb:46download-piped-to-shell (test/example)"curl -LsSf https://astral.sh/uv/install.sh | sh\n",
URLs to bare IP addresses (2)
WhereRuleMatch
tests/test_image_resource_loader.py:20ip-literal-url_GLOBAL_IP_URL = "http://93.184.216.34/image.png"
tests/test_service_client_sdk_unit.py:3320ip-literal-url("https://8.8.8.8/artifact.zip", True),
Committed binaries (1)
  • tests/data/epub/sources/epub_purvis_poetry.epub: JAR, 403 KB
Worst known vulnerabilities (5 of 5)
AdvisorySeverityPackageSummary
GHSA-gm37-52c6-37mwhighpymdown-extensions@10.21.3pymdown-extensions: exponential-backtracking ReDoS in caret, tilde, betterem, and magiclink inline processors
GHSA-9xwg-3r6f-jcx2moderatepymdown-extensions@10.21.3PyMdown Extensions: Path traversal in the b64 extension lets <img src> read files outside base_path
GHSA-h35f-9h28-mq5cmoderatesetuptools@81.0.0setuptools: MANIFEST.in exclusion bypass in sdist via Unicode normalization collision (NFC/NFD) on macOS APFS/HFS+
GHSA-rrmf-rvhw-rf47lowtorch@2.11.0PyTorch is vulnerable to memory corruption through its torch.jit.script function
CVE-2026-66007unknowndatasets@2.21.0
Workflows worth a look

By the numbers

Stars68K
Forks4,934
Contributors324
Commits1,489
Open issues811
Open pull requests135
Releases217
Latest releasev2.130.0
LicenceMIT
Main languagePython
Project age2 years
Last pushSep 25, 2026
Tracked files1,772
Lines of code645.3K
Checkout size187 MB

Lines by language: JSON 436.4K, Python 153.1K, Markdown 32.2K, Jupyter 14K, HTML 4,380, YAML 3,181.

Questions

Is Docling free?

Yes. Docling is MIT-licensed and free for commercial use, and there is no paid tier in the project. The layout and table models its standard pipeline downloads from Hugging Face are published under their own open licences. If you plug in a remote vision-language model or a third-party OCR engine, that service's terms and costs apply separately.

Does Docling need a GPU?

No. The standard PDF pipeline runs on a CPU and uses a CUDA GPU or Apple's MPS when one is available, which mainly speeds up large batches. The vision-language pipeline, GraniteDocling and larger models, is where a GPU starts to matter. The first conversion downloads the models; after that, conversion runs without a network connection.

How does Docling compare with Unstructured or Marker?

All three turn documents into text for AI pipelines. Docling's strengths are table structure and reading order from its own layout models, a rich JSON document model rather than plain text, and a permissive MIT licence. Marker focuses on PDF-to-Markdown quality under a GPL licence; Unstructured covers more connectors and sells a hosted API. For tables in PDFs, try Docling first.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.