OCRmyPDF
Add a searchable OCR text layer to scanned PDFs
OCRmyPDF is an open-source tool that adds a searchable text layer to scanned PDF files so they can be searched and copied. It is widely used as the OCR engine behind paperless document workflows.
Key features
- Searchable OCR text layer
- Preserves original PDF quality
- Batch processing
- Many language packs
Pros & cons
Strengths
- Excellent OCR results
- Composes well with other tools
Trade-offs
- Command-line focused
- Not a full DMS by itself
OCRmyPDF replaces
Last reviewed Aug 26, 2026 · 861 words
ocrmypdf --skip-text --deskew --rotate-pages -l eng scan.pdf searchable.pdf
That line is 90% of what I have ever asked OCRmyPDF to do. It takes a scanned PDF, straightens crooked pages, turns upside-down ones the right way up, runs Tesseract over every page image, and writes a PDF/A file that looks identical but can be searched, copied from and indexed. The scan's pixels are not touched. It is a command-line tool and nothing else, and that is why it is the OCR engine inside Paperless-ngx, Docspell and a dozen other document systems: it does one job to a standard nobody else matches for free.
The 4 flags that matter
--skip-text skips pages that already carry a text layer, so you can point OCRmyPDF at a mixed folder of born-digital and scanned files without wrecking the former. --redo-ocr is the careful alternative: it strips an existing (usually bad) OCR layer and replaces it while leaving real vector text alone. --force-ocr rasterises everything and OCRs it, which is the sledgehammer for PDFs with broken text layers and the wrong choice for anything else. And -l takes a plus-joined list (-l deu+eng) with each language needing its Tesseract pack installed; pick the languages actually on the page, because every extra one slows recognition and adds errors.
The cleanup options are worth a sentence each. --deskew and --rotate-pages are free wins on real scans. --clean runs unpaper to remove noise before OCR; add --clean-final only if you want the cleaned image saved, which changes the archived scan and which I avoid. --optimize 3 (needs pngquant and jbig2enc) shrinks output aggressively; the default level 1 is lossless.
What it changes and what it leaves alone
Output is PDF/A-2b by default, an archival format that embeds fonts and forbids things like JavaScript; add --output-type pdf if a downstream tool complains. The recognised text goes in as an invisible layer positioned over the words, so highlighting in a viewer lines up with the image. Bookmarks, page labels and most metadata survive; annotations and form fields generally do not survive --force-ocr, since the page is re-rendered. It does not rename, sort, tag or store anything, which is the "not a full DMS by itself" in its cons column and is exactly right. Feed it into a system that does those things.
Paperless-ngx runs it for you, so when do you call it yourself
Paperless-ngx wraps OCRmyPDF and exposes its behaviour as PAPERLESS_OCR_MODE (skip, redo or force) and PAPERLESS_OCR_LANGUAGE; the Paperless guide covers those. Three cases justify the direct call. First, an existing archive of thousands of scans you want searchable in place, on a NAS, without importing them anywhere. Second, PDFs you must hand to other people and want searchable regardless of what they use to read them. Third, big batches that are better run once on the fastest machine you own than trickled through a consumption folder on a NAS with 2 cores. Files you want the layout tools for, such as merging, splitting or redacting, belong in Stirling PDF, which can also call OCRmyPDF from its web UI.
Batching a folder without a DMS
The tool is single-file in, single-file out, so batching is a shell loop plus the --jobs flag, which parallelises across pages within one file:
mkdir -p done
for f in *.pdf; do
ocrmypdf --skip-text --deskew --jobs 4 -l eng "$f" "done/$f" || echo "FAILED $f"
done
For a machine with 8 cores, two files at --jobs 4 in parallel beats one at --jobs 8. Memory is modest; the catalogue's 512 MB floor is right for typical A4 scans, while 600 dpi colour pages can take 1 GB or more per job. If installing Python and Tesseract on the host is unappealing, the official image bundles a handful of common languages and works as a drop-in:
docker run --rm -v "$PWD:/data" jbarlow83/ocrmypdf --skip-text -l eng /data/in.pdf /data/out.pdf
The project also ships a watched-folder mode in the same image, which turns it into a poor man's consumption pipeline with about 4 environment variables.
Errors you will meet, and what they mean
Exit code 6 with "page already has text" is not an error; it is OCRmyPDF refusing to double-OCR, and --skip-text or --redo-ocr is the answer. Encrypted PDFs are rejected outright; run qpdf --decrypt first. "Tesseract data not found" means the language pack is missing (tesseract-ocr-deu and friends on Debian). Digitally signed PDFs are refused too, because any change would invalidate the signature, and that refusal is correct.
What I'd do
Install it from apt or the container, OCR the historical archive once with --skip-text --deskew --rotate-pages and the languages you actually have, then hand everything new to Paperless-ngx and never think about it again. Keep the originals until you have opened a sample of the outputs. Leave --force-ocr alone unless a file is genuinely broken.
Compare OCRmyPDF
2 head-to-head comparisons.
Similar document management apps
Stirling PDF
Document ManagementPowerful locally hosted web-based PDF toolkit
Replaces Adobe Acrobat, Smallpdf
Paperless-ngx
Document ManagementDocument management for scanning, indexing and archiving
Replaces Evernote, DEVONthink
DocuSeal
Document ManagementOpen-source document signing and e-signature platform
Replaces DocuSign, HelloSign
BentoPDF
Document ManagementPowerful, privacy-first, client-side PDF toolkit that allows you
Replaces Adobe Acrobat
Documenso
Document ManagementThe open-source DocuSign alternative
Replaces DocuSign, Adobe Sign
Filestash
Document ManagementWeb-based file manager and document gateway
Replaces Dropbox, SharePoint