OCRmyPDF takes a scanned PDF, the kind that is just pictures of pages, and adds an invisible text layer underneath so you can search it, select text and copy it out. The images are left at their original resolution, the output is a valid PDF/A file suitable for archiving, and the file is often smaller than the one you started with.
It is on this list because it does one job and does it reliably. It uses the Tesseract OCR engine, supports more than 100 languages, can straighten crooked pages and fix rotated ones, spreads work across all your CPU cores, and handles documents with thousands of pages. Everything runs on your own machine, so private paperwork stays private, and paperless-ngx uses it as its OCR step.
The limits: it is a command line tool, and accuracy is Tesseract's, which is good on clean printed text and weaker on handwriting or poor scans. Plugins can swap in other engines, such as EasyOCR, PaddleOCR or Apple's Vision framework.
- Repository: github.com/ocrmypdf/OCRmyPDF
- Licence: MPL-2.0 (Mozilla Public License 2.0)
- Language: Python. Stars: 35.2K. Forks: 2,441. Last push: Oct 25, 2026.
- Scan: safe, Oct 26, 2026, commit b457e9e
Who it is for
Anyone digitising paper records, people with a pile of scanned PDFs they cannot search, and developers who need OCR in a document pipeline.
Getting started
1. Install (macOS shown; Debian and Ubuntu: apt install ocrmypdf; Fedora: dnf install ocrmypdf)
brew install ocrmypdf2. Make a scanned PDF searchable
ocrmypdf input_scanned.pdf output_searchable.pdf3. OCR a French and English document and straighten the pages
ocrmypdf -l eng+fra --deskew input.pdf output.pdfLanguages other than English need Tesseract's language packs, for example brew install tesseract-lang on macOS.
Safety scan
We cloned ocrmypdf/OCRmyPDF at commit b457e9e on Oct 26, 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 installer scripts and no bare-IP URLs in about 62,000 lines, mostly Python.
- The 19 flagged binaries are all pdf.bin files under tests/cache: cached Tesseract output the test suite replays so tests run without the OCR engine. They are not part of the installed package.
- uv.lock covers 144 Python packages, and none has a known advisory.
- Three workflows, none using pull_request_target. All 20 third-party actions are pinned to tags rather than commits. Dependabot present; no security policy or CodeQL.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | None found. |
| Install-time code | None: nothing runs at install beyond the package manager itself. |
| Committed binaries | 19 executable or compiled objects committed; listed under the raw findings. |
| CI workflows | 3 workflows. None use pull_request_target. 20 of 20 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 14 distinct hosts referenced from source; most often github.com, ns.adobe.com, www.aiim.org, ocrmypdf.readthedocs.io. No URLs to bare IP addresses. |
| Known vulnerabilities | 0 advisories across 144 pinned packages: 0 critical, 0 high, 0 moderate, 0 low. uv.lock: 144 packages, 0 advisories. |
| Project hygiene | Has automated dependency updates, licence file. Missing security policy, CodeQL, contributing guide. |
| OpenSSF Scorecard | Not 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.
Committed binaries (19)
tests/cache/v1/skew-6be6b54d/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 13 KBtests/cache/v1/jbig2-210b845b/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/cardinal-ebd7b223/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/cardinal-ebd7b223/__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/cardinal-ebd7b223/__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/cardinal-ebd7b223/__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/ccitt-5f4b129b/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/multipage-07987c44/__-l__eng__000005_ocr.png__000005_ocr_tess__pdf__txt/pdf.bin: .bin, 10 KBtests/cache/v1/multipage-07987c44/__-l__eng__000006_ocr.png__000006_ocr_tess__pdf__txt/pdf.bin: .bin, 8 KBtests/cache/v1/multipage-07987c44/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 6 KBtests/cache/v1/francais-600c27f8/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 4 KBtests/cache/v1/multipage-07987c44/__-l__eng__000004_ocr.png__000004_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/palette-bc2d0a67/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/multipage-07987c44/__-l__eng__000003_ocr.png__000003_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/graph-11fa2cef/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/multipage-07987c44/__-l__eng__000002_ocr.png__000002_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/aspect-1585370a/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/skew-6be6b54d/__-l__eng__--psm__7__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KBtests/cache/v1/lichtenstein-d7f2f944/__-l__eng__000001_ocr.png__000001_ocr_tess__pdf__txt/pdf.bin: .bin, 3 KB
By the numbers
| Stars | 35.2K |
|---|---|
| Forks | 2,441 |
| Contributors | 130 |
| Commits | 4,574 |
| Open issues | 62 |
| Open pull requests | 5 |
| Releases | 66 |
| Latest release | v17.13.0 |
| Licence | MPL-2.0 |
| Main language | Python |
| Project age | 12 years |
| Last push | Oct 25, 2026 |
| Tracked files | 573 |
| Lines of code | 62.4K |
| Checkout size | 12 MB |
Lines by language: Python 51.1K, Markdown 9,324, YAML 1,098, TOML 468, Shell 461, JSON 7.
Questions
Is OCRmyPDF free?
Yes. OCRmyPDF is free under the Mozilla Public License 2.0, which allows commercial use and use inside closed-source software, but asks you to publish changes you make to OCRmyPDF's own files.
Does OCRmyPDF upload my documents anywhere?
No. It runs Tesseract and Ghostscript locally, and nothing leaves your computer.
Can OCRmyPDF read handwriting?
Not well. Tesseract is built for printed text. Plugins that use other OCR engines can do better on difficult pages, at the cost of more setup.
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.
