---
title: An Alternative to cordova-plugin-document-scanner
description: Looking for a cordova-plugin-document-scanner alternative? Compare the unmaintained Cordova plugin with the Capacitor Document Scanner plugin and map its API.
date:
  created: 2026-10-13
  updated: 2026-10-13
authors:
  - robingenz
categories:
  - Capacitor
  - Cordova
  - Guides
  - SDKs
links:
  - Capacitor Document Scanner: sdks/capacitor/document-scanner.md
faq: true
---

# An Alternative to cordova-plugin-document-scanner

Teams searching for a cordova-plugin-document-scanner alternative usually arrive after a failed build: an App Store validation error about unsupported architectures, a linker error on a current Xcode, or an Android scan that returns the cancel message although the user confirmed the page. The Cordova plugin received its last release in 2021, and the native scanner libraries it bundles have not moved since. This post compares it with the [Capacitor Document Scanner plugin](../../sdks/capacitor/document-scanner.md), maps every option of the old API to the new one, and lists what behaves differently after the switch. The Capacitor plugin is part of [Capawesome Insiders](../../insiders/index.md).

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Ship a fix in one command with Capawesome Cloud Live Updates, no store review" src="https://capawesome.io/assets/banners/cloud-ship-a-fix-in-one-command.png" />
  </a>
</div>

**Key takeaways:**

- cordova-plugin-document-scanner is unmaintained: the last commit on master dates from February 2021, the last npm release (4.2.7) from October 2021, and 30 issues are open without a fix.
- Its iOS side ships prebuilt frameworks with simulator slices that fail App Store validation, and its Android side relies on an OpenCV fork with recurring low-memory crashes.
- The Capacitor Document Scanner plugin uses the ML Kit Document Scanner on Android and VisionKit on iOS, with a two-method API, multi-page results and optional PDF output.
- `scan.scanDoc(success, error, options)` becomes `scanDocument(options)`, callbacks become a typed promise, and `returnBase64`, `fileName` and the 1 to 5 `quality` scale have no direct equivalent.
- The Capacitor plugin is a paid Insiders plugin and needs Google Play services on Android; `@capacitor-mlkit/document-scanner` is a free, Android-only option.

## Maintenance status

cordova-plugin-document-scanner is unmaintained, although neither npm nor GitHub says so. The [repository](https://github.com/NeutrinosPlatform/cordova-plugin-document-scanner){:target="_blank"} is not archived and the package is not flagged as deprecated, so the dates have to tell the story (all checked on 2026-10-12):

| Fact | Value |
| --- | --- |
| Last commit on master | 2021-02-11 (5.0.0-beta.1) |
| Latest stable release on npm | 4.2.7, published 2021-10-14 |
| Open issues | 30, plus 2 open pull requests |
| Newest open issue | #114, 2025-08-18, no maintainer reply |
| Weekly downloads | 82 |

The open issues describe the plugin breaking under each new platform release rather than a feature wish list. Issue #111 (2023) reports App Store validation failing with "Unsupported Architectures" because the embedded `IRLDocumentScanner` and `TOCropViewController` frameworks still contain `i386` and `x86_64` simulator slices. Issue #109 reports an undefined symbol for `IRLScannerViewController` on Xcode 14.2. On Android, issue #106 covers the Android 11 storage restrictions, and issues #74, #108 and #112 report the same low-memory crash on Android 10, 12 and 13. Issue #114 from 2025 describes the plugin returning "Incorrect result or user canceled the action" on a successful scan with cordova-android 14 and target SDK 35. A request for Capacitor support (#105) has been open since 2022, and a request for multi-page scanning (#31) since 2018.

The native stack explains why these issues stay open. On Android, the plugin wraps `scanlibrary`, an OpenCV-based fork of an Android demo project, pulled from JitPack. On iOS, version 4.x switched from WeScan to the Objective-C `IRLDocumentScanner`, which is vendored as a prebuilt binary with a minimum OS version of 8.0. Updating either means rebuilding a third-party scanner library, not patching a plugin.

## What replaces it

The Capacitor Document Scanner plugin wraps the document scanners that Google and Apple ship themselves, instead of a third-party edge-detection library. On Android, that is the [ML Kit Document Scanner](https://developers.google.com/ml-kit/vision/doc-scanner/android){:target="_blank"}, which Google Play services download on demand; Google lists the cost as about 300 KB of download size and requires Android API level 21 and at least 1.7 GB of RAM. On iOS, it is VisionKit's `VNDocumentCameraViewController`, the same scanner that the Notes and Files apps use. The plugin requires Capacitor 8, iOS 15 and Android API level 24, and supports CocoaPods and Swift Package Manager.

The whole API is two methods. [`isAvailable()`](../../sdks/capacitor/document-scanner.md#isavailable) tells you whether the device can scan, and [`scanDocument(...)`](../../sdks/capacitor/document-scanner.md#scandocument) opens the native scanner, lets the user capture one or more pages, and resolves with the file paths of the corrected JPEG images and an optional PDF. [Announcing the Capacitor Document Scanner Plugin](./announcing-the-capacitor-document-scanner-plugin.md) walks through the API in detail.

Pricing is the trade-off to state upfront. cordova-plugin-document-scanner is free, and the Capacitor plugin is part of the paid Capawesome Insiders subscription. The free option in the Capacitor ecosystem is [`@capacitor-mlkit/document-scanner`](../../sdks/capacitor/mlkit/document-scanner.md), which wraps the same ML Kit scanner but supports Android only. For an app that ships on both platforms, the choice is between the Insiders plugin and keeping a Cordova plugin that no longer builds reliably.

## API mapping

The Capacitor Document Scanner plugin replaces the global `scan` object and its callbacks with an imported module and a typed promise. The table maps every option and callback of cordova-plugin-document-scanner 4.2.7 to its counterpart:

| cordova-plugin-document-scanner | Capacitor Document Scanner |
| --- | --- |
| Global `scan` object after `deviceready` | `import { DocumentScanner } from '@capawesome-team/capacitor-document-scanner'` |
| *No equivalent* | [`isAvailable()`](../../sdks/capacitor/document-scanner.md#isavailable) resolves with `{ available }` |
| `scan.scanDoc(success, error, options)` | [`scanDocument(options)`](../../sdks/capacitor/document-scanner.md#scandocument) resolves with `{ scannedImages, pdf }` |
| `successCallback(imageData)`, one string | `scannedImages`, an array with one `file://` path per page |
| `errorCallback("Cancelled")` or `errorCallback("Incorrect result or user canceled the action.")` | Rejection with the error code `SCAN_CANCELED` |
| Other error strings | Error codes `SCAN_FAILED` and `PDF_GENERATION_FAILED` |
| `sourceType: 0` (gallery, Android only) | `androidGalleryImportAllowed: true` adds an import option to the scanner UI |
| `sourceType: 1` (camera, default) | Default behavior |
| `quality: 1.0` to `5.0` (1 is best) | `imageQuality: 0` to `100` (100 is best, the default) |
| `returnBase64: true` | *No equivalent*; read the file with `@capacitor/filesystem` when you need base64 |
| `fileName` (iOS only) | *No equivalent*; files get unique names in the cache directory |
| Plugin variables `CAMERA_USAGE_DESCRIPTION` and `PHOTOLIBRARY_USAGE_DESCRIPTION` | `NSCameraUsageDescription` in `Info.plist`, no photo library key |
| *No equivalent* | `pageLimit` (default 10), `generatePdf`, `androidScannerMode` |

Two rows need a second look. The `quality` scales are not a linear conversion: the Cordova value reduces the resolution on Android by subsampling the image and applies JPEG compression on iOS, while `imageQuality` applies JPEG compression on both platforms and never changes the resolution. Teams that lowered `quality` to avoid the Android low-memory crash do not need the workaround anymore, because the ML Kit scanner runs in Google's process. And `sourceType: 0` opened the gallery directly, while `androidGalleryImportAllowed` shows the import option inside the scanner flow, so a "pick from gallery" button in your UI needs the scanner first.

## Migrating the scan call

A scan with cordova-plugin-document-scanner is a callback pair on a global object, called after `deviceready`:

```javascript
document.addEventListener('deviceready', () => {
  scan.scanDoc(
    imageData => {
      showScan(imageData);
    },
    message => {
      if (message !== 'Cancelled') {
        showError(message);
      }
    },
    { sourceType: 1, quality: 2.0, returnBase64: false },
  );
});
```

The same scan with the Capacitor Document Scanner plugin checks availability first, awaits the result and reads the error code instead of comparing strings:

```typescript
import { DocumentScanner } from '@capawesome-team/capacitor-document-scanner';

const scanPages = async () => {
  const { available } = await DocumentScanner.isAvailable();
  if (!available) {
    return [];
  }
  try {
    const { scannedImages } = await DocumentScanner.scanDocument({
      imageQuality: 80,
      pageLimit: 5,
    });
    return scannedImages;
  } catch (error) {
    if ((error as { code?: string }).code === 'SCAN_CANCELED') {
      return [];
    }
    throw error;
  }
};
```

The result is an array because the user can capture several pages in one session, up to `pageLimit`. With `generatePdf: true`, the same call also returns the path of a combined PDF in `pdf`, which replaces the hand-built PDF step that Cordova apps added after each single-page scan. [How to Scan a Document to PDF in a Capacitor App](./how-to-scan-a-document-to-pdf-in-a-capacitor-app.md) builds the full scan, view and share flow around that option.

Cancel handling becomes reliable in the move. On Android, cordova-plugin-document-scanner reports a cancel and a failed scan with the same message, which is the root of issue #114. The Capacitor plugin rejects with `SCAN_CANCELED` when the user leaves the scanner and with `SCAN_FAILED` when the scan itself fails, so the catch block can tell them apart.

## Permissions and setup

The Capacitor Document Scanner plugin needs one `Info.plist` key on iOS and no manifest changes on Android. On Android, Google's scanner activity requests the camera permission itself, so the app declares nothing and the plugin adds nothing. On iOS, the plugin reads `NSCameraUsageDescription` and rejects with a clear error when the key is missing instead of crashing.

That removes three permissions from the Cordova setup. cordova-plugin-document-scanner requested `CAMERA`, `READ_EXTERNAL_STORAGE` and `WRITE_EXTERNAL_STORAGE` at runtime on Android, and the storage permissions are what broke under the scoped storage rules of Android 11, reported in issue #106. On iOS, it required a camera and a photo library usage description through plugin variables, where the Capacitor plugin never touches the photo library. The one platform requirement that is new is Google Play services on Android, since the scanner module is downloaded through them; `isAvailable()` returns `false` on devices without them.

## What behaves differently

Scanning with the Capacitor Document Scanner plugin changes five things beyond the method names, and each of them removes a workaround that Cordova apps carried.

- **Scanner UI**: the plugin shows the operating system's scanner, which cannot be styled and looks different on Android and iOS. The Cordova plugin's third-party UI could be patched, and its edge detection was the subject of several open issues. On Android, `androidScannerMode` picks between crop and rotate only (`Base`), with filters (`BaseWithFilter`), and the default `Full` mode that also removes stains, fingers and shadows.
- **Multi-page results**: `scannedImages` holds one path per page, up to `pageLimit`. Android enforces the limit inside the scanner, and iOS cannot, so the plugin truncates the result after the scan on iOS.
- **Storage location**: the Cordova plugin wrote to the public `Pictures` folder on Android, so every scan appeared in the user's gallery (issue #63), and on iOS it overwrote `Documents/image.jpg` unless `fileName` changed between scans (issue #10). The Capacitor plugin writes to the app's cache directory with unique names and deletes stale files when the plugin loads. Copy the files you want to keep to `Directory.Data` with `@capacitor/filesystem` right after the scan.
- **Quality**: `imageQuality` compresses the JPEG without changing its resolution, on both platforms. There is no option to downscale, and the memory reason for doing so is gone.
- **Error handling**: errors arrive as rejections with a `code`, and a missing camera description on iOS is reported as an error rather than a crash. Issue #78 described the Cordova plugin crashing when the user refused the camera permission on iOS.

On the web, neither plugin scans. Both methods of the Capacitor plugin reject as unimplemented there, so a PWA build needs a file input as fallback.

## FAQ

### Is there a maintained replacement for cordova-plugin-document-scanner?

Yes. The [Capacitor Document Scanner plugin](../../sdks/capacitor/document-scanner.md) wraps the ML Kit Document Scanner on Android and VisionKit on iOS, supports multi-page scans and PDF output, and is maintained for Capacitor 8. It is a paid Insiders plugin. The free `@capacitor-mlkit/document-scanner` plugin covers Android only. cordova-plugin-document-scanner itself has had no release since 2021.

### Is the Capacitor Document Scanner plugin free?

No. The plugin is part of the [Capawesome Insiders](../../insiders/index.md) subscription and is installed from the Capawesome npm registry with the license key that comes with it.

### Does it work without Google Play services?

Not on Android. The ML Kit Document Scanner is a Google Play services module, so devices without them, such as recent Huawei phones, report `available: false` from `isAvailable()`. iOS is not affected. The Cordova plugin's OpenCV-based scanner had no such dependency, which is a real difference if those devices matter for your app.

### Can I still get the scan as base64?

Not from the plugin. `scanDocument(...)` always returns `file://` paths. Read a path with the `readFile(...)` method of `@capacitor/filesystem` when a backend expects base64, or display the image directly with `Capacitor.convertFileSrc(...)`, which avoids holding a large string in memory.

### Do I have to migrate my whole Cordova app first?

Yes. The Capacitor Document Scanner plugin is a Capacitor plugin and has no Cordova version. Capacitor can run most Cordova plugins during a migration, so the scanner can be the first plugin you replace after the move. [An Alternative to cordova-plugin-file-transfer](./alternative-to-cordova-plugin-file-transfer.md) covers the file transfer side of the same migration.

## Need Help Migrating Off Cordova?

A document scanner is often one of several Cordova plugins that stopped building, and the move to Capacitor touches the native projects, the plugins and the CI pipeline at once. We help teams plan and run that migration, including the switch from Ionic Appflow to Capawesome Cloud for builds and live updates.

[Book an Ionic Appflow Migration Demo](https://cal.com/team/capawesome/ionic-appflow-migration){ .md-button .md-button--primary }

## Conclusion

If your app targets both platforms and ships through the App Store, replace cordova-plugin-document-scanner now rather than after the next Xcode release breaks the vendored frameworks again. Map the scan call with the table above, drop the `quality` and storage workarounds, and copy the results out of the cache directory before you do anything else with them. For a single-platform Android app that needs a free option, `@capacitor-mlkit/document-scanner` uses the same ML Kit scanner. [Cordova Hot Code Push Alternative for OTA Updates](./cordova-hot-code-push-alternative.md) covers the next Cordova plugin most teams replace.

If you have any questions, join us on the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"}. To stay updated on the latest news, subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"}.
