MakeACopy is an open-source offline document scanner with OCR for Android, designed for privacy-friendly and self-hosted document workflows.
It allows you to digitize paper documents into searchable PDFs while keeping the entire processing pipeline on your device. The app works completely offline and avoids any cloud services, telemetry, or tracking.
MakeACopy is designed to be a reliable building block for privacy-friendly document workflows, especially when combined with self-hosted storage systems.
With the discontinuation of Microsoft Lens, many users are looking for a reliable way to scan documents on Android.
MakeACopy offers the same core building blocks — document scanning, OCR, and searchable PDF export — while following a fundamentally different design:
Instead of integrating into a cloud ecosystem, MakeACopy focuses on local processing and interoperability with tools like SambaLite, paperless-ngx, and Syncthing.
This makes it especially suitable for users who prefer control, privacy, and predictable behavior over cloud-based convenience features.
MakeACopy can be combined with SambaLite to create a fully automated mobile document workflow:
Paper document
↓
Scan with MakeACopy
↓
Inbox folder
↓
SambaLite folder sync
↓
NAS / archive (e.g. paperless-ngx)
This setup effectively turns your smartphone into a privacy-friendly mobile network scanner for self-hosted document archives.
MakeACopy treats privacy and offline operation as technical design decisions, not as moral or political statements. The app works fully offline, is open source, and avoids tracking or cloud services because this results in a simpler, more robust, and more auditable system. Users are encouraged to evaluate MakeACopy based on its concrete features and implementation rather than on positioning or narratives.
To ensure fully offline operation, MakeACopy bundles OCR language models, fonts, and image processing components locally. This significantly increases the app size, but avoids any cloud dependencies or on-demand downloads.
100 MB are not a sign of excess, but of consistency.
MakeACopy is available in two editions (controlled via the Gradle property edition):
| Edition | OCR Languages | Fonts | APK Size (arm64-v8a) |
|---|---|---|---|
| Full | 23 languages (incl. CJK, Arabic, Hindi, Thai, Turkish) | 5 fonts (incl. CJK, Devanagari) | ~99 MB |
| Light | English + German | 1 font (NotoSans) | ~58 MB |
Both editions include the same ML-based document detection (ONNX model), OpenCV image processing, and full offline functionality. Both editions use an operator-stripped ONNX Runtime build that includes only the operators required for document detection. The Light edition additionally ships fewer OCR language models and fonts, and uses a minimal ONNX Runtime AAR without XNNPACK and NNAPI to further reduce APK size.
In addition, MakeACopy is built in two product flavors (ocr flavor dimension):
| Flavor | OCR Backend | Notes |
|---|---|---|
| paddle | PaddleOCR V5 | Published flavor for F-Droid and Google Play. Uses PaddleOCR only, without Tesseract runtime, Tesseract language data, or OCR dictionaries. |
| standard | Tesseract only | Legacy flavor for existing Tesseract language data and workflows. Available via GitHub Releases. No PaddleOCR assets bundled. |
The Full + paddle combination is what is published on F-Droid and Google Play. The standard Tesseract flavor and the Light edition are available via GitHub Releases.
Or download the latest APK from the Releases Section.
All official releases of MakeACopy are signed with one of the following certificates:
Upload key (used for GitHub releases, F-Droid, and sideload APKs)
SHA-256: AE:32:2D:3F:B7:1A:FE:21:DF:47:27:E3:7A:5C:68:03:51:1D:5A:2F:E1:FC:31:35:43:0C:EE:06:99:FA:1B:34
Google Play App Signing key (used for Play Store releases)
SHA-256: C0:71:44:39:CB:51:62:32:A4:47:91:7A:6F:C2:28:1E:45:FA:AA:DD:37:F8:30:B1:01:1F:B4:85:68:8E:0D:64
apksigner verify --print-certs MakeACopy-vX.Y.Z.apk
paddle flavorMakeACopy supports fully offline OCR. The published paddle flavor uses PaddleOCR; choose the closest script or language group in the OCR language selector during the OCR step.
Supported out of the box: - English (English) - German (Latin), French (Latin), Italian (Latin), Spanish (Latin), Portuguese (Latin), Dutch (Latin), Polish (Latin), Czech (Latin), Slovak (Latin), Hungarian (Latin), Romanian (Latin), Danish (Latin), Norwegian (Latin), Swedish (Latin), Turkish (Latin) - Chinese (Simplified) (Chinese), Chinese (Traditional) (Chinese) - Russian (East Slavic), Thai (Thai) - Arabic (Arabic), Persian/Farsi (Arabic) - Hindi (Devanagari) - Greek (Greek)
In the paddle flavor, select the visible OCR language group for your document:
| Document language | Choose in the OCR language selector |
|---|---|
| English | English |
| German, French, Italian, Spanish, Portuguese, Dutch, Polish, Czech, Slovak, Hungarian, Romanian, Danish, Norwegian, Swedish, Turkish | Latin |
| Chinese Simplified or Traditional | Chinese |
| Russian | East Slavic |
| Thai | Thai |
| Arabic and Persian/Farsi | Arabic |
| Hindi | Devanagari |
| Greek | Greek |
The F-Droid and Google Play links point to the paddle flavor. Use GitHub Releases if you need the standard Tesseract flavor.
Notes: - All OCR runs fully offline on-device. - For Chinese, MakeACopy includes appropriate CJK fonts for better PDF text embedding. - For Arabic and Persian, MakeACopy includes the Noto Naskh Arabic font for proper RTL (right-to-left) text rendering in PDF exports. - For Hindi, MakeACopy includes the Noto Sans Devanagari font for proper Devanagari text rendering in PDF exports.

MakeACopy is F-Droid compliant. The F-Droid listing provides the paddle flavor. The app builds all required native components from source during CI/local builds:
external/opencv.external/onnxruntime via scripts/build_onnxruntime_android.sh. The resulting artifacts are integrated into app/src/main/jniLibs/<ABI>/ (e.g., libonnxruntime.so, libonnxruntime4j_jni.so) and app/libs/ (onnxruntime-*.jar).This approach ensures F-Droid compatibility by not including any pre-compiled binaries in the repository and building OpenCV and ONNX Runtime native components from source.
You can download the latest APKs from the Releases page. Use GitHub Releases if you need the standard Tesseract flavor or the Light edition.
All automated builds are handled by a single GitHub Actions workflow:
The workflow contains two parallel jobs:
Full build (build):
- Sets up JDK 21 (Temurin) and installs Android NDK 28.0.13004108
- Pins CMake 3.31.6 and Python 3.11.2 for deterministic native builds
- Checks out submodules (external/opencv and external/onnxruntime)
- Builds OpenCV native libraries from source via scripts/build_opencv_android.sh
- Collects reproducibility evidence for native builds (scripts/collect_repro_evidence.sh)
- Integrates OpenCV artifacts into the app via scripts/prepare_opencv.sh
- Builds ONNX Runtime for Android (XNNPACK and NNAPI, Java bindings) via scripts/build_onnxruntime_android.sh — the operator config supports DocQuad corner detection and PaddleOCR V5
- Builds the Full edition Android app with Gradle for both flavors (paddle and standard), producing the published Paddle artifacts and the Tesseract legacy artifacts
- Verifies that no test data leaks into release APKs via :app:verifyNoTestDataInApk
- Renames artifacts to MakeACopy-vX.Y.Z-<abi>-release.apk (standard) and MakeACopy-vX.Y.Z-<abi>-paddle-release.apk (paddle), plus release AABs
Light build (build-light):
- Depends on the Full build job and downloads the native libraries (jniLibs and JARs) built from source
- Sets up JDK 21 only (no native build scripts needed)
- Builds the Light edition for the standard flavor only: ./gradlew :app:assembleStandardRelease -Pedition=light (PaddleOCR is not part of the Light edition)
- Produces per-ABI APKs named MakeACopy-Light-vX.Y.Z-<abi>-release.apk
Behavior by event type:
- Push/PR to main (non-tag):
- Builds unsigned artifacts (Full: Release AAB and per-ABI Release APKs; Light: per-ABI Release APKs)
- Uploads all artifacts for download from the workflow run
- Tag (refs/tags/vX.Y.Z):
- Optionally decodes a keystore from repository secrets and signs the builds
- Verifies APK signatures using apksigner
- Renames artifacts to MakeACopy-vX.Y.Z-<abi>-release.apk (standard), MakeACopy-vX.Y.Z-<abi>-paddle-release.apk (paddle), MakeACopy-Light-vX.Y.Z-<abi>-release.apk, plus release AABs
- Generates SHA-256 c
$ claude mcp add makeacopy \
-- python -m otcore.mcp_server <graph>