npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@valifysolutions/crossplatform-capacitor-vidvdockit

v1.0.1

Published

Capacitor plugin for the VIDV DocKit identity verification and document capture SDK (Android & iOS).

Readme

@valifysolutions/crossplatform-capacitor-vidvdockit

Capacitor plugin for the VIDV DocKit identity verification and document capture SDK, on Android and iOS.

This plugin is a thin bridge — all document capture, OCR, liveness, and NFC logic lives in the native SDKs. The plugin only:

  1. Maps a JS DocKitConfig onto the native builder (VIDVDocKitConfig.Builder on Android, VIDVDocBuilder on iOS).
  2. Starts the native SDK's own UI flow (an Activity on Android, a modally-presented flow on iOS).
  3. Maps the native result callback back into a resolved Capacitor call.
                              JS/TS  →  DocKit.start(config)
                                            │
                    ┌───────────────────────┴───────────────────────┐
                    ▼                                                ▼
   DocKitPlugin (Android)  ──build──▶  VIDVDocKitConfig.Builder     DocKitPlugin (iOS)  ──build──▶  VIDVDocBuilder
            │                                    │                          │                                │
            │                              builder.start(activity, listener)│                    builder.start(viewController, delegate)
            │                                    ▼                          │                                ▼
            │                          VidvDocKitHostActivity (SDK UI)      │                      SDK presents its own flow modally
            │                                    │                          │                                │
            │              VIDVDocKitListener.onDocKitResult(response)     │        VIDVDocKitDelegate.onDocKitResult(response)
            ◀────────────────────────────────────┘                          ◀────────────────────────────────┘
                    Promise<DocKitResponse>                                          Promise<DocKitResponse>

Your app's MainActivity/AppDelegate need no changes — Capacitor's plugin autolinking (npx cap sync) discovers and registers DocKitPlugin automatically from this package's capacitor.android.src / capacitor.ios.src fields, the same way every other Capacitor plugin does.

Install

npm install @valifysolutions/crossplatform-capacitor-vidvdockit
npx cap sync

Android

The native SDK is resolved from Valify's private Artifactory repo, which this plugin's android/build.gradle already registers. If you have your own Artifactory credentials, override the defaults in your app's android/gradle.properties:

valifyArtifactoryUser=your-user
valifyArtifactoryPassword=your-password

Your app must declare the INTERNET permission (Capacitor apps already do). Camera, location (only if collectUserInfo is enabled) and NFC permissions/manifest entries come from the SDK's own AAR and are requested at runtime by the SDK's own Activity — no action needed in your app.

iOS

The native VIDVDocKit XCFramework (currently v1.7.1) is vendored automatically by this plugin's own ValifysolutionsCrossplatformCapacitorVidvdockit.podspec (CocoaPods) — no extra Podfile entry needed beyond the usual pod install that npx cap sync ios already runs for you. CocoaPods is the only supported iOS integration path — this plugin has no Package.swift/Swift Package Manager manifest, so apps using SPM for their own dependencies must still integrate this plugin (and VIDVDocKit) via CocoaPods.

Add the permission usage strings the native SDK needs to your app's Info.plist (these mirror the original iOS SDK Demo's own Info.plist):

<key>NSCameraUsageDescription</key>
<string>We need access to your camera to scan documents.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to provide relevant features and improve your app experience.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need access to your location even when the app is in the background to support continuous services.</string>
<key>NFCReaderUsageDescription</key>
<string>This app reads your biometric passport chip</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
  <string>A0000002471001</string>
</array>

(NSLocation* and NFCReaderUsageDescription/the NFC AID entry are only exercised when collectUserInfo is enabled or documentType is ePassport, respectively — but iOS requires the usage strings to be present whenever the SDK binary links the relevant frameworks, regardless of whether your own config path uses them.)

Your app also needs the Near Field Communication Tag Reading capability (adds com.apple.developer.nfc.readersession.formats: [TAG] to your entitlements) if you use documentType: 'ePassport'.

iOS Simulator is not supported. The published VIDVDocKit.xcframework currently ships a device-only (arm64) slice with no Simulator slice at all — this plugin's podspec excludes simulator architectures so a Simulator build of your app doesn't hard-fail at link time, but the DocKit flow itself only runs on a physical device.

Usage

import { DocKit } from '@valifysolutions/crossplatform-capacitor-vidvdockit';

const response = await DocKit.start({
  baseUrl: 'https://api.valifystage.com',
  accessToken: myAccessToken,
  bundleKey: myBundleKey,
  documentType: 'egyNID',

  language: 'en',
  reviewData: true,
  captureMode: 'automatic',
  extras: ['advanced_confidence', 'document_liveness'],
});

switch (response.state) {
  case 'SUCCESS':
    console.log('Captures:', response.result?.captures);
    console.log('Extracted data:', response.result?.extractedData);
    break;
  case 'FAILURE':
    console.warn(`DocKit failed (${response.code}): ${response.message}`);
    break;
  case 'EXIT':
    console.log(`User exited at step: ${response.step}`);
    break;
  case 'ERROR':
    console.error(`Invalid configuration (${response.code}): ${response.message}`);
    break;
}

DocKit.start() only rejects for conditions outside the SDK's own result model — no foreground Activity on Android (NO_ACTIVITY), no presentable view controller on iOS (NO_VIEW_CONTROLLER), or a config-building failure such as an invalid primaryColor hex string (INIT_ERROR). Every SDK outcome, including user cancellation and validation/service failures, resolves the promise with the corresponding state — see "Android/iOS differences" below for the one exception (missing/invalid documentType).

API

start(...)

start(options: DocKitConfig) => Promise<DocKitResponse>

Launches the VIDV DocKit SDK with the given configuration and resolves with the session outcome once the SDK's own UI finishes.

| Param | Type | | ------------- | ---------------------------------------------------- | | options | DocKitConfig |

Returns: Promise<DocKitResponse>

Interfaces

DocKitConfig

Configuration for a DocKit session. Field names are camelCase (idiomatic Capacitor/TypeScript style); each is mapped 1:1 to a setter on the native builder — VIDVDocKitConfig.Builder on Android, VIDVDocBuilder on iOS — except where noted as platform-specific.

| Field | Type | Required | Default | Android setter | iOS setter | | ---------------------------- | -------------------------------------------------------------------------------- | :------: | ------------- | ---------------------------------- | ------------------------------------ | | baseUrl | string | ✅ | — | setBaseUrl | setBaseURL | | accessToken | string | ✅ | — | setAccessToken | setAccessToken | | bundleKey | string | ✅ | — | setBundleKey | setBundleKey | | documentType | DocumentType | ✅ | — | setDocumentType | setDocumentType | | language | Language | | en | setLanguage | setLanguage | | reviewData | boolean | | true | setReviewData | setReviewData | | collectUserInfo | boolean | | false | setCollectUserInfo | setCollectUserInfo | | previewCapturedImage | boolean | | false | previewCapturedImage | setPreviewCapturedImage | | captureMode | CaptureMode | | automatic | setCaptureMode | setCaptureMode | | captureModeSeconds | number | | 10 | VIDVCaptureMode.AUTO_AFTER(secs) | VIDVCaptureMode.manualAfter(secs) | | captureOnlyMode | boolean | | false | setCaptureOnlyMode | setCaptureOnlyMode | | epassportSecurityConfig | boolean | | true | setEPassportSecurityConfig | ignored — no iOS equivalent as of SDK 1.7.1 | | manualCaptureValidation | boolean | | false | manualCaptureValidation | ignored — no iOS equivalent | | primaryColor | string (hex, e.g. "#62CBC9") | | native default | setPrimaryColor | setPrimaryColor | | headers | Record<string, string> | | {} | setHeaders | setHeaders | | sslCertificate | string (base64) | | — | setSSLCertificate | setSSLCertificate | | customLogo | string (base64) | | — | setLogo(ByteArrayLogo(...)) | setLogo(.customLogo(...)) | | disableLogo | boolean | | false | setLogo(Empty()) | setLogo(.empty) | | customFontResourceName | string (Android font resource name, e.g. "custom_font") | | — | setCustomFont(resId) | ignored — see customFontName | | customFontName | string (iOS font/family name, e.g. "HelveticaNeue-Bold") | | — | ignored | setCustomFont(UIFont(name:size:)) | | customFontSize | number | | 16 | ignored | (used with customFontName) | | extras | ExtrasConfig | | [] | setExtras | setExtras | | documentValidation | DocumentValidationRuleConfig[] | | | documentValidation | ignored — no iOS equivalent |

customFontResourceName (Android) and customFontName/customFontSize (iOS) can't ship a font file on your behalf the way customLogo/sslCertificate do — both platforms require the font to already be bundled/registered by your own app. On Android, bundle a .ttf (or font-family XML) under android/app/src/main/res/font/ and pass its resource name (without extension). On iOS, register the font (e.g. via UIAppFonts in Info.plist, or CTFontManagerRegisterFontsForURL) and pass its PostScript/family name. A name that doesn't resolve falls back to the SDK's default font on Android; on iOS it fails DocKit.start() with INIT_ERROR instead, since there's no silent "ignore and use default" case to fall back to at the point the font would be constructed.

DocKitResponse

| Field | Type | Set for | | ------------ | ------------------------------------------------------------ | ------------------------- | | state | DocKitState | always | | code | number | FAILURE, ERROR | | message | string | FAILURE, ERROR | | step | string | EXIT | | result | DocKitResultData | SUCCESS, and often FAILURE/EXIT |

DocKitResultData

Mirrors me.vidv.vidvdockitsdk.global.VIDVDocKitData on Android and VIDVDocumentKitResult on iOS.

| Field | Type | Platform | | -------------------- | ----------------------------------------------- | --------------------- | | sessionID | string | both | | deviceID | string | Android only | | captures | Record<string, string \| null> (base64 JPEG) | both* | | extractedData | Record<string, unknown> | both | | validationFailures | DocumentValidationFailure[] | Android only | | validations | NFCValidations | iOS only |

* Same type on both platforms, but not the same presence guarantee — see "Android/iOS differences" below.

NFCValidations

iOS only. NFC passive authentication / MRZ cross-check / face match detail, populated for ePassport sessions. Mirrors the native VIDVNFCValidations struct.

| Field | Type | | ----------------------- | ---------------------------------------------------------- | | passiveAuthentication | { status?: boolean; reason?: string } | | mrzCrossCheck | { status?: string; mismatchedFields?: string[] } | | faceMatchValidation | { status?: boolean } |

DocumentValidationRuleConfig

| Field | Type | Notes | | --------------- | ---------------------------------------------------------------------- | --------------------------------------------- | | path | string | Dot-notation path into extractedData | | op | DocumentValidationOperator | | | value | string \| number \| boolean | Not used for IS_TRUE/IS_FALSE/IS_EMPTY/IS_NOT_EMPTY/MATCH | | matchPath | string | For MATCH: path to compare against instead of value | | ignoreValues | string[] | For IS_EMPTY: extra values treated as empty |

Type Aliases

DocumentType

'passport' | 'ePassport' | 'egyNID' | 'tunNID' | 'dzaNID'

CaptureMode

'automatic' | 'manual' | 'autoAfter'

Language

'en' | 'ar' | 'fr'

ExtrasConfig

string[] | Record<string, boolean>

DocKitState

'SUCCESS' | 'FAILURE' | 'EXIT' | 'ERROR'

DocumentValidationOperator

'EQUAL' | 'NOT_EQUAL' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL' | 'IS_TRUE' | 'IS_FALSE' | 'IS_EMPTY' | 'IS_NOT_EMPTY' | 'CONTAINS' | 'NOT_CONTAINS' | 'MATCH'

Design notes / deviations from the React Native plugin

The React Native DocKit plugin was used as the reference for this plugin's architecture and API surface, and the native Android DocKit SDK as the source of truth for all native behavior. A few things are deliberately different from the RN plugin:

  • camelCase field names (baseUrl, documentType, captureMode, …) instead of RN's snake_case — idiomatic for Capacitor/TypeScript. The underlying native calls are identical.
  • captureMode: 'automatic' | 'manual' | 'autoAfter' — the native SDK's VIDVCaptureMode sealed class has no MANUAL_AFTER variant; RN accepted 'manual_after' as an alias that silently mapped to AUTO_AFTER. This plugin exposes a single canonical 'autoAfter' name instead.
  • No deprecated manualCapture boolean — RN kept it for its own backward compatibility. This is a new plugin with no existing consumers, and the SDK itself deprecates that flag in favor of captureMode.
  • No validations/NFCValidations field in the result — that field is iOS-only in RN (populated from ePassport NFC checks on iOS). The Android VIDVDocKitData model has no such field, so it is correctly omitted here rather than invented.

Everything else — every config option, every result field, every error code (7000-7018), and the resolve-vs-reject contract — is preserved exactly as the native Android SDK and the RN plugin define it.

Android/iOS differences

The native iOS DocKit SDK (distributed as the VIDVDocKit.xcframework, and its own Demo app) is the source of truth for all iOS behavior — it is not assumed to work like the Android SDK. Every difference below comes from a real difference between the two native SDKs, not from a choice made in this plugin:

  • documentValidation and manualCaptureValidation have no equivalent in the native iOS SDK's public API. Both are accepted in DocKitConfig for shape parity and silently ignored on iOS — result.validationFailures will never be populated there.
  • result.validations (NFCValidations) is iOS-only, populated from the native VIDVDocumentKitResult. The Android SDK's result model has no such field.
  • result.deviceID is Android-only — the iOS result model has no such field.
  • result.captures presence — on Android, every expected capture key is always present, with null for a side that wasn't captured (e.g. { front: "...", back: null }). On iOS, the native VIDVDocumentKitResult.captures only includes keys for sides that were actually captured, so an uncaptured side is missing from the object entirely rather than set to null (e.g. { front: "..." }, with no back key at all). Check for absence (captures.back == null) rather than captures.back === null if you need identical behavior on both platforms.
  • customFontResourceName (Android) vs. customFontName/customFontSize (iOS) — see the DocKitConfig table above.
  • epassportSecurityConfig is Android only. As of native iOS SDK 1.7.1, VIDVDocBuilder no longer exposes a setter for ePassport NFC security checks (BAC/PACE/passive authentication) — the SDK handles them internally and they are not configurable from outside it. The option is accepted for DocKitConfig shape parity and silently ignored on iOS.
  • Missing/invalid documentType rejects with INIT_ERROR on Android (reading an unassigned Kotlin lateinit throws before the SDK's own Activity ever starts), but resolves state: 'ERROR' (code 7018) on iOS, where VIDVBuilderValidator catches it and reports it through the normal delegate/result path. This plugin does not paper over that difference — see DocKit.start()'s doc comment.
  • Invalid language — Android's native SDK silently falls back to English for an unrecognized value; the iOS SDK's own validator rejects it as state: 'ERROR' (code 7018) instead. (Both platforms' public Language type only allows 'en' | 'ar' | 'fr', so this only matters for direct/dynamic JS callers that bypass the type.)
  • No Simulator support on iOS — the published XCFramework ships a device-only slice today.

Development

npm install
npm run build        # tsc + rollup, both platforms share the same dist output
npm run verify:android  # ./gradlew clean build test

The example/ app demonstrates both platforms from the same JS/TS code — npx cap sync inside example/ after npm run build in the plugin root picks up local changes.