5 min read

Marker: Convert PDFs and Documents to Clean Markdown (GitHub, Scanned)

Turn PDFs, Office files and ebooks into clean Markdown, JSON or HTML, tables and equations intact.

Marker logo
✅
Scan: safe. Nothing malicious. Check the model weights' licence before commercial use, and note that the pinned development environment carries advisories a normal pip install avoids. Scanned Oct 22, 2026; the full report is below.

Marker converts documents into Markdown, JSON, HTML or chunks ready for an AI pipeline. Feed it a PDF, an image, a Word, PowerPoint or Excel file, an HTML page or an EPUB, and it returns text in reading order with tables formatted as tables, equations as LaTeX, code as code blocks, links and references preserved, images saved alongside, and page headers and footers removed. It works in any language.

Under the hood it uses Datalab's Surya vision model for layout and OCR, served locally through vLLM on an NVIDIA GPU or llama.cpp on a CPU or Apple Silicon Mac, and starts that server for you on first use. A balanced mode re-reads whole pages when their embedded text is bad; a fast mode suited to CPUs keeps model use minimal. Add --use_llm to have a language model merge tables across pages, fix inline math and pull values out of forms. There is a command for single files, one for whole folders, a Python API, and a small web app for trying settings.

The code is Apache 2.0, with about 40,600 stars, at v2.0.0 when scanned. The model weights carry a modified OpenRAIL-M licence: free for research, personal use and startups under 5 million dollars in funding or revenue.

  • Repository: github.com/datalab-to/marker
  • Licence: Apache-2.0 (Apache License 2.0)
  • Language: Python. Stars: 40.6K. Forks: 2,936. Last push: Oct 19, 2026.
  • Scan: safe, Oct 22, 2026, commit 1749c21

Who it is for

Developers building retrieval or training pipelines from PDFs, researchers turning papers into editable text, and anyone who has fought with copy and paste out of a multi-column PDF.

Getting started

1. Install (Python 3.10 or newer with PyTorch; use marker-pdf[full] for Office and EPUB files)

pip install marker-pdf

2. On a Mac or CPU, install the llama.cpp server the OCR model runs on (NVIDIA users need Docker instead)

brew install llama.cpp

3. Convert one file

marker_single paper.pdf --output_format markdown

4. Convert a whole folder

marker ./pdfs

The first run downloads the models. Use --page_range to test on a few pages, --force_ocr for scans with bad embedded text, and --disable_ocr for clean digital PDFs when you want speed over completeness.

Safety scan

We cloned datalab-to/marker at commit 1749c21 on Oct 22, 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.

  • No secrets, no suspicious code patterns, no committed binaries and no install hooks across 265 files and about 94,000 lines (most of it JSON test data; the Python is about 17,000 lines).
  • The hosts in the code are the optional LLM services (Gemini by default, plus OpenAI, OpenRouter and Azure) and models.datalab.to for model downloads. With --use_llm off, documents are processed only on your machine.
  • 117 known advisories (5 critical) in uv.lock, the pinned development environment. The criticals are in certifi, GitPython and Pillow image decoding. pip install marker-pdf resolves newer versions within its ranges, which avoids most of them.
  • Licensing is split: the code is Apache 2.0, the model weights are free for research, personal use and smaller companies, and larger commercial users need a licence from Datalab.
  • 4 workflows. One uses pull_request_target for the CLA bot and does not check out the pull request; none of the 5 third-party actions is pinned to a commit. Licence present; no security policy, Dependabot or CodeQL.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious codeNone found.
Install-time codeNone: nothing runs at install beyond the package manager itself.
Committed binariesNone.
CI workflows4 workflows. 1 uses pull_request_target, none check out the pull request head. 5 of 5 third-party actions pinned to a tag rather than a commit.
Network hosts5 distinct hosts referenced from source; most often github.com, openrouter.ai, api.openai.com, models.datalab.to. No URLs to bare IP addresses.
Known vulnerabilities117 advisories across 257 pinned packages: 5 critical, 69 high, 39 moderate, 4 low. uv.lock: 257 packages, 117 advisories.
Project hygieneHas licence file. Missing security policy, automated dependency updates, CodeQL, contributing guide.
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.

Worst known vulnerabilities (24 of 117)
AdvisorySeverityPackageSummary
GHSA-6q48-6c7w-9gw2criticalcertifi@2026.6.17certifi bundles emSign root CAs with compromised intermediate CA keys
GHSA-284h-m62q-gf8wcriticalgitpython@3.1.53GitPython: Dormant multi-line git-config values are corrupted into live injected directives (e.g. core.hooksPath) on any…
GHSA-332p-7hrc-92wfcriticalpillow@10.4.0Pillow: Heap buffer overflow in _tiffWriteProc when saving TIFF to BytesIO
GHSA-8g5g-8vmr-9782criticalpillow@10.4.0Pillow: Heap buffer overflow in ImagingJpegDecode
GHSA-w889-685w-c8fhcriticalpillow@10.4.0Pillow: Argument Injection in Ghostscript call, potentially leading into RCE
GHSA-2g87-pp6c-29x5highaiohttp@3.14.1aiohttp: Multiple instances of excessive or unbounded memory/CPU use
GHSA-5wr8-gcqf-gqf3highaiohttp@3.14.1aiohttp server lacks an initial request/header timeout
GHSA-9xw5-w5jj-pvcghighaiohttp@3.14.1AIOHTTP: File descriptor exhaustion in multipart requests
GHSA-cq5v-8q36-5273highaiohttp@3.14.1AIOHTTP: Out-of-bounds heap read in C HTTP response parser error path (malformed chunked response)
GHSA-g6cj-pr64-35w5highcryptography@49.0.0cryptography: PKCS#7 EnvelopedData decryption exposes a Bleichenbacher oracle through distinguishable errors and timing
GHSA-27vj-qcqg-25rchighfsspec@2026.4.0fsspec: Server-Side Template Injection in ReferenceFileSystem leads to Remote Code Execution
GHSA-239g-whfq-7xj9highgitpython@3.1.53GitPython: Repository content can impersonate the git directory, leading to arbitrary code execution
GHSA-3f7w-8rr8-f37fhighgitpython@3.1.53GitPython: Unguarded git option forwarding in IndexFile.checkout() and TagReference.create() enables arbitrary file over…
GHSA-4gmw-gg2m-w46phighgitpython@3.1.53GitPython: Unguarded git read-tree option forwarding in IndexFile.from_tree/reset/merge_tree enables arbitrary file over…
GHSA-6p8h-3wgx-97gfhighgitpython@3.1.53GitPython: Incomplete unsafe_git_clone_options denylist omits --template enabling arbitrary command execution via clone …
GHSA-7833-fr7j-v32qhighgitpython@3.1.53GitPython: Arbitrary local file content disclosure via [include] directive in untrusted .gitmodules (SubmoduleConfigPars…
GHSA-8mcc-hrx5-hvxchighgitpython@3.1.53GitPython: clone_from()/clone() omit --separate-git-dir from unsafe_git_clone_options, enabling arbitrary git-directory …
GHSA-94p4-4cq8-9g67highgitpython@3.1.53GitPython: Environment-variable exfiltration via Repo.create_remote() / Remote.add() URL (incomplete fix of GHSA-rwj8-pg…
GHSA-9rj7-rf2p-w77rhighgitpython@3.1.53GitPython: Unguarded git option forwarding in Repo.init enables arbitrary command execution via --template clone hooks
GHSA-fjr4-x663-mwxchighgitpython@3.1.53GitPython: Arbitrary file overwrite via git diff --output argument injection in Diffable.diff (key- and value-controlled…
GHSA-g5vv-9gxw-82hxhighgitpython@3.1.53GitPython: Denial of Service via catastrophic backtracking (ReDoS) in Actor.name_email_regex - commit author/committer f…
GHSA-hmq2-w58f-27jchighgitpython@3.1.53GitPython: Arbitrary Git Repository Creation Outside the Working Tree via Unvalidated .gitmodules Submodule Name in GitP…
GHSA-jm78-9fvv-mhgrhighgitpython@3.1.53GitPython: git-config OPTION-name injection via =/#/whitespace bypasses name validator, enabling forged core.sshCommand/…
GHSA-r9mr-m37c-5fr3highgitpython@3.1.53GitPython: Unsafe git option guard bypass via single-character kwarg value token smuggling enables arbitrary command exe…
Workflows worth a look

By the numbers

Stars40.6K
Forks2,936
Contributors29
Commits1,402
Open issues385
Open pull requests109
Releases72
Latest releasev2.0.0
LicenceApache-2.0
Main languagePython
Project age2 years
Last pushOct 19, 2026
Tracked files265
Lines of code93.8K
Checkout size14 MB

Lines by language: JSON 66.1K, Python 16.6K, Markdown 10.7K, YAML 165, Shell 89, TOML 80.

Questions

Is Marker free?

The code is free under Apache 2.0. The model weights are free for research, personal use and organisations under 5 million dollars in funding or revenue; above that, commercial use needs a licence from Datalab, which also sells a hosted API.

How does Marker compare with Docling or MarkItDown?

MarkItDown is a lightweight converter that mostly extracts existing text. Docling and Marker both run layout and OCR models, so they handle scans, tables and equations. Marker is strong on equations and optional LLM cleanup; Docling's code is MIT-licensed with permissively licensed default models, which is simpler for commercial use.

Does Marker need a GPU?

No. Its fast mode runs on a CPU or an Apple Silicon Mac through llama.cpp, which is fine for occasional documents. For large batches or the most accurate balanced mode, an NVIDIA GPU with vLLM is far faster.


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.