In this tutorial, we’ll use Capacitor with Ionic and Angular to build a cross-platform app for Android and iOS that scans documents and exports them as PDF files.
To implement the document scanning functionalities, PDF generation, and app UI, we’ll use the Scanbot Capacitor Document Scanner SDK.

Building our app involves the following steps:
- Preparing the project
- Installing the SDK
- Initializing the SDK
- Implementing the scanning feature
- Implementing the PDF export feature
Requirements
Before starting development with Capacitor, you need to set up your environment.
The prerequisites for developing Ionic Capacitor apps are:
Core requirements:
- Node.js version 20.19 or higher
For iOS development:
- iOS 14+
- macOS with Xcode 16+
- Xcode Command Line Tools
- Homebrew
- Cocoapods
For Android development:
- Android Studio Jellyfish | 2024.2.1+
- Android SDK (API Level 22+), Platforms and Developer Tools
- Android Gradle Plugin 8.4.0+ or Kotlin Plugin applied
To get the full benefits and experience from using our SDK, we also recommend real devices for testing.
Developing Capacitor applications can be done via the CLI or using the VS Code extension. In this tutorial, we’ll use CLI commands. However, feel free to follow along using whatever option suits you best.
Capacitor can be used with different frameworks. In this tutorial, we will use Capacitor with Ionic and Angular. Again, these choices depend on your needs and prior knowledge.
Since we’ll use Ionic in this tutorial, you also need to install the Ionic CLI if you haven’t already:
npm install -g @ionic/cli
Step 1: Prepare the project
1. Create a new Capacitor project
To start creating your Capacitor app with Ionic using the CLI, run the following command in the terminal, which will create a blank project with some recommended Capacitor dependencies:
ionic start CapacitorTutorial blank --capacitor --type angular-standalone --package-id io.scanbot.tutorial.capacitor
⚠️ When using your own license, make sure that the package ID is the same as the application/bundle ID associated with it.
2. Generate the native projects
Now, let’s add the Android and iOS platforms to our project.
Navigate into the project directory.
cd CapacitorTutorial
Then add Android and iOS as platforms.
npm i @capacitor/android @capacitor/ios
And run the following commands to create the native Android and iOS projects:
npx cap add android
npx cap add ios
Step 2: Install file-viewer and the Document Scanner SDK
First, install file-viewer, the Capacitor plugin that we’ll use to open and preview our generated PDF files:
npm i @capacitor/file-viewer
Next, install the Capacitor Document Scanner SDK:
npm i capacitor-plugin-scanbot-sdk
💡 This will install the latest Scanbot SDK version. You can find more information about each version in the changelog.
Now that the npm package has been installed, we need to make some changes to the native projects.
For Android, we need to add the camera permission and feature in android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
For iOS, we need to include a description for the camera permission in ios/App/App/Info.plist anywhere inside the <dict>
element:
<key>NSCameraUsageDescription</key>
<string>Camera permission is needed to scan documents</string>
Now that the project is set up, we can start integrating the document scanning functionalities.
Step 3: Initialize the SDK
Before using any feature of the Scanbot SDK, we need to initialize it. Ideally, initialization should be done as soon as the app is launched.
In this tutorial, we’re going to initialize the SDK inside a ngOnInit
callback in src/app/app.component.ts. Make sure to import OnInit
and ScanbotSDK
.
Your app.component.ts will look like this:
import { Component, OnInit } from '@angular/core';
import { IonApp, IonRouterOutlet } from '@ionic/angular/standalone';
import { ScanbotSDK } from 'capacitor-plugin-scanbot-sdk';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
imports: [IonApp, IonRouterOutlet],
})
export class AppComponent implements OnInit {
constructor() { }
ngOnInit(): void {
ScanbotSDK.initializeSDK({
licenseKey: ""
}).then(result => console.log(result))
.catch(err => console.log(err));
}
}
💡 Without a license key, our SDK only runs for 60 seconds per session. This is more than enough for the purposes of our tutorial, but if you like, you can generate a license key using the bundle and application identifiers.
Step 4: Implement the scanning feature
In your project folder, go to scr/app/home/home.page.html, and add a button inside the container div that will start the scanning process.
<ion-button (click)="startDocumentScanner()">Start Document Scanner</ion-button>
We need to define the startDocumentScanner
function inside the HomePage
class in scr/app/home/home.ts. Make sure that ScanbotSDK
, DocumentScanningFlow
and startDocumentScanner
are imported and IonButton
is added in the component imports.
In this tutorial, we use a default configuration object. It will start the Document Scanner UI with the default settings: in multi-page scanning mode with an acknowledge screen after scanning each page. You can customize the UI and behavior of the Document Scanner by modifying the configuration object. For more information on how to do that, please refer to the SDK’s RTU UI documentation.
Your home.ts should look something like this:
import { Component } from '@angular/core';
import { IonHeader, IonToolbar, IonTitle, IonContent, IonButton } from '@ionic/angular/standalone';
import { ScanbotSDK } from 'capacitor-plugin-scanbot-sdk';
import { startDocumentScanner, DocumentScanningFlow } from 'capacitor-plugin-scanbot-sdk/ui_v2';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
imports: [IonHeader, IonToolbar, IonTitle, IonContent, IonButton],
})
export class HomePage {
constructor() { }
async startDocumentScanner() {
try {
/** Check license status and return early if the license is not valid */
if (!(await ScanbotSDK.getLicenseInfo()).isLicenseValid) {
return;
}
/**
* Create the document configuration object and
* start the document scanner with the configuration
*/
const configuration = new DocumentScanningFlow();
const documentResult = await startDocumentScanner(configuration);
/**
* Handle the result if the result status is OK
*/
if (documentResult.status === 'OK') {
/* Print out the documentImageURI for each page */
documentResult.data.pages.forEach((page) => console.log(page.documentImageURI));
}
} catch (e: any) {
console.log("An error has occurred while running Document Scanner", e.message);
}
}
}
Step 5: Implement the PDF export feature
Now, we will generate a PDF file from the scanned document.
Make sure to add FileViewer
and PdfConfiguration
to the imports in home.page.ts:
import { ScanbotSDK, PdfConfiguration } from 'capacitor-plugin-scanbot-sdk';
import { FileViewer } from '@capacitor/file-viewer';
To enable users to scan documents and generate a PDF, we need to modify the startDocumentScanner
method. This method will first launch the document scanner, then process the scanned document to generate a PDF file, and finally open it.
async startDocumentScanner() {
try {
/** Check license status and return early if the license is not valid */
if (!(await ScanbotSDK.getLicenseInfo()).isLicenseValid) {
return;
}
/**
* Create the document configuration object and
* start the document scanner with the configuration
*/
const configuration = new DocumentScanningFlow();
const documentResult = await startDocumentScanner(configuration);
/**
* Handle the result if the result status is OK
*/
if (documentResult.status === 'OK') {
/* Print out the documentImageURI for each page */
documentResult.data.pages.forEach((page) => console.log(page.documentImageURI));
/* Create a PDF configuration objet */
const pdfConfiguration = new PdfConfiguration();
/* Create a PDF file from the provided document UUID and the configuration object */
const createPDFResult = await ScanbotSDK.Document.createPDF({
documentID: documentResult.data.uuid,
pdfConfiguration: pdfConfiguration
});
/* Open the created PDF file */
await FileViewer.openDocumentFromLocalPath({
path: createPDFResult.pdfFileUri
});
}
} catch (e: any) {
console.log("An error has occurred while running Document Scanner", e.message);
}
}
Now you can open a scanned document as a PDF file and share it. For example, you can send it via email or save it to a cloud storage.
In the terminal, run these commands to build and sync the native projects:
npm run build
npx cap sync
To run the app on Android and iOS, use the following commands:
For Android:
npx cap run android
For iOS:
To run the app on a real iOS device, you need to adjust the “Provisioning” and “Signing” settings. Open ios/App/App.xcworkspace with Xcode, adjust the settings, and run the project from Xcode or with this command:
npx cap run ios

Conclusion
And that’s it! You’ve successfully integrated a fully functional document scanner into your app 🎉
If this tutorial has piqued your interest in integrating document scanning functionalities into your Capacitor app, make sure to take a look at the other neat features in the Capacitor Document Scanner SDK’s documentation – or run our example project for a more hands-on experience.
Should you have questions about this tutorial or run into any issues, we’re happy to help! Just shoot us an email via tutorial-support@scanbot.io.
Happy scanning! 🤳