cordova-plugin-synapse-qr-scanner
v1.0.0
Published
Production-ready Cordova QR and barcode scanner with Android Google Code Scanner / CameraX + ML Kit fallback and iOS AVFoundation.
Downloads
16
Maintainers
Readme
cordova-plugin-synapse-qr-scanner
Cordova plugin for QR and barcode scanning on Android and iOS. Plugin Cordova para escaneo de códigos QR y de barras en Android e iOS.
Built and maintained by Synapse. Desarrollado y mantenido por Synapse.
GitHub repository: mendel81/cordova-plugin-synapse-qr-scanner Repositorio GitHub: mendel81/cordova-plugin-synapse-qr-scanner
English
Overview
cordova-plugin-synapse-qr-scanner is a native scanner plugin for Cordova projects that need a modern, low-friction setup and clean coexistence with cordova-plugin-firebasex.
Highlights:
- Android uses
autoengine selection:- Google Code Scanner first when the request is compatible and Google Play Services is available.
- CameraX + ML Kit fallback when Google Code Scanner is unavailable or the request needs a custom live-scanner UI.
- iOS uses
AVFoundationdirectly, with no third-party iOS scanning dependency. - Promise-first JavaScript API with optional Cordova-style callbacks.
- Normalized results across platforms.
- No manual edits required in
Gradle,Podfile,AndroidManifest.xml, orInfo.plist.
This plugin does not apply google-services, does not depend on deprecated Firebase ML Vision artifacts, and does not inject extra iOS pods.
It is an independent community plugin. It is not an official Apache Cordova plugin and is not affiliated with Apache, Google, Apple, or Firebase.
Install
From npm:
cordova plugin add cordova-plugin-synapse-qr-scannerFrom a local checkout:
cordova plugin add /absolute/path/to/plugin-folderOptional install-time overrides:
cordova plugin add cordova-plugin-synapse-qr-scanner \
--variable CAMERA_USAGE_DESCRIPTION="Scan inventory labels with the camera." \
--variable ANDROIDX_CAMERA_VERSION=1.6.0 \
--variable MLKIT_BARCODE_SCANNING_VERSION=17.3.0 \
--variable PLAY_SERVICES_CODE_SCANNER_VERSION=16.1.0JavaScript API
The plugin is exposed as:
window.NativeCodeScannercordova.plugins.nativeCodeScanner
Promise-based usage:
const result = await NativeCodeScanner.scan({
formats: ['QR_CODE', 'EAN_13', 'CODE_128'],
prompt: 'Aim at the code',
preferFrontCamera: false,
showTorchButton: true,
showFlipCameraButton: false,
beepOnSuccess: true,
vibrateOnSuccess: false,
timeoutMs: 0,
androidEngine: 'auto',
returnRawBytes: false
});
if (!result.cancelled) {
console.log(result.text, result.format, result.engine);
}Optional callback wrapper:
NativeCodeScanner.scan(
{ formats: ['QR_CODE'] },
function onSuccess(result) {
console.log(result);
},
function onError(error) {
console.error(error.code, error.message);
}
);API surface:
isSupported(): Promise<SupportInfo>checkPermission(): Promise<PermissionInfo>requestPermission(): Promise<PermissionInfo>scan(options?): Promise<ScanResult>cancel(): Promise<void>prewarm(): Promise<void>
TypeScript definitions ship in types/index.d.ts.
Supported format names:
QR_CODEAZTECPDF_417DATA_MATRIXCODABARCODE_39CODE_93CODE_128EAN_8EAN_13ITFUPC_AUPC_E
Engine behavior
Android
androidEngine accepts:
autogooglemlkit
auto selects Google Code Scanner when:
- Google Play Services is available
- the device has a camera
- the request does not require custom live-scanner UI
auto falls back to CameraX + ML Kit when the request needs features Google Code Scanner does not expose directly, including:
promptpreferFrontCamerashowTorchButtonshowFlipCameraButtontimeoutMsvibrateOnSuccessbeepOnSuccess: false
If androidEngine: 'google' is forced with incompatible options, the plugin rejects with INCOMPATIBLE_OPTIONS.
iOS
iOS always uses the native AVFoundation implementation.
Permission model
Android
Permissions are reported from the point of view of the default auto engine.
- If Google Code Scanner is available,
checkPermission()may resolve withgranted: trueandrequiresPermission: falseeven before camera permission is granted. - If the request resolves to the ML Kit engine, camera permission is required and the plugin requests it automatically during
scan()when possible.
iOS
Live scanning always requires camera permission.
Supported formats by platform
| Format | Android Google | Android ML Kit | iOS AVFoundation |
| --- | --- | --- | --- |
| QR_CODE | Yes | Yes | Yes |
| AZTEC | Yes | Yes | Yes |
| PDF_417 | Yes | Yes | Yes |
| DATA_MATRIX | Yes | Yes | Yes |
| CODABAR | Yes | Yes | Yes, iOS 15.4+ |
| CODE_39 | Yes | Yes | Yes |
| CODE_93 | Yes | Yes | Yes |
| CODE_128 | Yes | Yes | Yes |
| EAN_8 | Yes | Yes | Yes |
| EAN_13 | Yes | Yes | Yes |
| ITF | Yes | Yes | Yes |
| UPC_A | Yes | Yes | Yes, normalized from EAN-13 subset on iOS |
| UPC_E | Yes | Yes | Yes |
iOS normalization notes:
UPC_Ais normalized from theEAN_13subset when the scanned value starts with0and the request asked forUPC_AwithoutEAN_13.ITFis normalized frominterleaved2of5andITF14.CODABARdepends on iOS 15.4+ runtime support fromAVFoundation.
Result contract
Successful scan:
{
"cancelled": false,
"text": "0123456789012",
"format": "EAN_13",
"nativeFormat": "EAN_13",
"engine": "google",
"platform": "android",
"rawBytesBase64": null,
"valueType": "PRODUCT",
"bounds": { "left": 0, "top": 0, "width": 100, "height": 50 },
"cornerPoints": [{ "x": 0, "y": 0 }],
"timestamp": 1713072000000
}User cancellation resolves normally:
{
"cancelled": true,
"text": null,
"format": null,
"nativeFormat": null,
"engine": "mlkit",
"platform": "android",
"rawBytesBase64": null,
"valueType": "UNKNOWN",
"bounds": null,
"cornerPoints": [],
"timestamp": 1713072000000
}Error codes
Common codes:
INVALID_ARGUMENTINVALID_FORMATINVALID_ENGINESCAN_IN_PROGRESSUNSUPPORTEDGOOGLE_SCANNER_UNAVAILABLEINCOMPATIBLE_OPTIONSPERMISSION_DENIEDPERMISSION_RESTRICTEDCAMERA_UNAVAILABLETORCH_FAILEDUNSUPPORTED_FORMATSCAN_FAILEDRESULT_ENCODING_FAILEDUI_UNAVAILABLE
Firebasex compatibility
Validated against [email protected].
Compatibility rules:
- No
google-servicesplugin application. - No Firebase SDK dependency.
- No deprecated Firebase ML Vision artifacts.
- No iOS CocoaPods dependency injection.
- No mutation of Firebasex variables or Gradle plugin setup.
- Android dependencies are limited to Google Code Scanner, CameraX, ML Kit Barcode Scanning, and a small Guava runtime dependency used by the CameraX provider future type.
What was validated:
cordova plugin addin a clean Cordova Android app- Android debug APK build
- iOS simulator build
- install and
preparewith[email protected]
The Firebasex smoke app intentionally stops at prepare, because Firebasex itself requires real Firebase config files to complete a native build.
Licensing and publication
The repository source is licensed under Apache License 2.0, which keeps it aligned with the license family used by Apache Cordova and many official Cordova plugins.
Important nuance:
- This repository is Apache-2.0.
- AndroidX and Guava dependencies are Apache-2.0.
Google Play Services Code ScannerandGoogle ML Kit Barcode Scanningare distributed under ML Kit Terms of Service.- iOS uses Apple system frameworks and adds no third-party pods.
That means the plugin can be published on GitHub and npm under Apache-2.0, while Android teams should still review ML Kit terms as part of their own compliance process.
See:
Example app
A minimal example UI lives in example-app/www.
Development
Tests:
npm testSmoke tests:
npm run smoke:android
npm run smoke:ios
npm run smoke:firebasex
npm run smoke:all:latest-cli
npm run smoke:firebasex:latest-cliPerformance benchmark:
npm run perf:benchThis benchmark covers JavaScript API normalization overhead with a mocked native bridge and hot paths for isSupported(), checkPermission(), scan(), and cancellation normalization.
It does not measure physical camera startup time, live Android frame analysis throughput, or device-specific iOS camera latency.
Packaging check:
npm run pack:checkManual device check
npx -y [email protected] create native-scanner-smoke com.acme.nativescanner NativeScannerSmoke
cd native-scanner-smoke
npx -y [email protected] platform add [email protected]
npx -y [email protected] platform add [email protected]
npx -y [email protected] plugin add /absolute/path/to/plugin-folderThen:
- copy the sample UI from
example-app/www - run
npx -y [email protected] run android --device - or run
npx -y [email protected] run ios --device - verify
isSupported(),requestPermission(),prewarm(),scan(), cancellation, torch toggle, and at least one QR and one linear barcode scan
Publishing checklist
- Run
npm test - Run
npm run smoke:android - Run
npm run smoke:ios - Run
npm run smoke:firebasex - Run
npm run smoke:all:latest-cli - Run
npm run smoke:firebasex:latest-cli - Run
npm run perf:bench - Run
npm run pack:check - Review
THIRD_PARTY_LICENSES.mdif dependency versions changed
Publish to npm
The package name is currently available as an unscoped public package. Before the first publish:
- Sign in to npm:
npm login
npm whoami- Run the release checks:
npm test
npm run smoke:all:latest-cli
npm run smoke:firebasex:latest-cli
npm run perf:bench
npm run pack:check- Publish version
1.0.0:
npm publish- Verify the package:
npm view cordova-plugin-synapse-qr-scanner versionExpected install command:
cordova plugin add cordova-plugin-synapse-qr-scannerFor later releases:
npm version patch
npm publishnpm currently requires either 2FA enabled on the account or a granular access token with bypass 2FA enabled for publishing.
Notes
prewarm()is best-effort:- Android tries to warm Google Code Scanner when possible.
- iOS is a safe no-op.
cancel()is best-effort:- Android ML Kit activity and the iOS custom scanner can be dismissed.
- Android Google Code Scanner is a safe no-op because the system UI is external.
scanFromImage()is intentionally left out of v1 to keep the live-camera path stable first.
Español
Resumen
cordova-plugin-synapse-qr-scanner es un plugin nativo de escaneo para proyectos Cordova que necesitan una instalación sencilla, mantenimiento razonable y buena convivencia con cordova-plugin-firebasex.
Puntos clave:
- En Android usa selección automática de motor:
- Primero Google Code Scanner cuando la petición es compatible y Google Play Services está disponible.
- Fallback a CameraX + ML Kit cuando hace falta una UI de escaneo propia o Google Code Scanner no está disponible.
- En iOS usa
AVFoundationdirectamente, sin dependencias iOS de terceros. - API JavaScript orientada a Promises, con callbacks estilo Cordova opcionales.
- Resultados normalizados entre plataformas.
- Instalación sin tocar
Gradle,Podfile,AndroidManifest.xmlniInfo.plist.
Este plugin no aplica google-services, no depende de Firebase ML Vision y no inyecta pods extra en iOS.
Es un plugin comunitario e independiente. No es un plugin oficial de Apache Cordova ni está afiliado a Apache, Google, Apple o Firebase.
Instalación
Desde npm:
cordova plugin add cordova-plugin-synapse-qr-scannerDesde un checkout local:
cordova plugin add /absolute/path/to/plugin-folderOverrides opcionales en instalación:
cordova plugin add cordova-plugin-synapse-qr-scanner \
--variable CAMERA_USAGE_DESCRIPTION="Escanear etiquetas con la cámara." \
--variable ANDROIDX_CAMERA_VERSION=1.6.0 \
--variable MLKIT_BARCODE_SCANNING_VERSION=17.3.0 \
--variable PLAY_SERVICES_CODE_SCANNER_VERSION=16.1.0API JavaScript
El plugin se expone como:
window.NativeCodeScannercordova.plugins.nativeCodeScanner
Uso con Promises:
const result = await NativeCodeScanner.scan({
formats: ['QR_CODE', 'EAN_13', 'CODE_128'],
prompt: 'Apunta al código',
preferFrontCamera: false,
showTorchButton: true,
showFlipCameraButton: false,
beepOnSuccess: true,
vibrateOnSuccess: false,
timeoutMs: 0,
androidEngine: 'auto',
returnRawBytes: false
});
if (!result.cancelled) {
console.log(result.text, result.format, result.engine);
}Wrapper opcional con callbacks:
NativeCodeScanner.scan(
{ formats: ['QR_CODE'] },
function onSuccess(result) {
console.log(result);
},
function onError(error) {
console.error(error.code, error.message);
}
);Superficie de API:
isSupported(): Promise<SupportInfo>checkPermission(): Promise<PermissionInfo>requestPermission(): Promise<PermissionInfo>scan(options?): Promise<ScanResult>cancel(): Promise<void>prewarm(): Promise<void>
Las definiciones TypeScript están en types/index.d.ts.
Formatos soportados:
QR_CODEAZTECPDF_417DATA_MATRIXCODABARCODE_39CODE_93CODE_128EAN_8EAN_13ITFUPC_AUPC_E
Comportamiento del motor
Android
androidEngine acepta:
autogooglemlkit
auto elige Google Code Scanner cuando:
- Google Play Services está disponible
- el dispositivo tiene cámara
- la petición no necesita UI personalizada de escaneo en vivo
auto hace fallback a CameraX + ML Kit cuando la petición necesita opciones que Google Code Scanner no expone directamente, como:
promptpreferFrontCamerashowTorchButtonshowFlipCameraButtontimeoutMsvibrateOnSuccessbeepOnSuccess: false
Si fuerzas androidEngine: 'google' con opciones incompatibles, el plugin rechaza con INCOMPATIBLE_OPTIONS.
iOS
iOS usa siempre la implementación nativa basada en AVFoundation.
Modelo de permisos
Android
Los permisos se informan desde el punto de vista del motor por defecto auto.
- Si Google Code Scanner está disponible,
checkPermission()puede resolver congranted: trueyrequiresPermission: falseaunque el permiso de cámara todavía no se haya concedido. - Si la petición acaba usando ML Kit, el permiso de cámara es obligatorio y el plugin lo solicita automáticamente durante
scan()cuando es posible.
iOS
El escaneo en vivo siempre requiere permiso de cámara.
Formatos soportados por plataforma
| Formato | Android Google | Android ML Kit | iOS AVFoundation |
| --- | --- | --- | --- |
| QR_CODE | Sí | Sí | Sí |
| AZTEC | Sí | Sí | Sí |
| PDF_417 | Sí | Sí | Sí |
| DATA_MATRIX | Sí | Sí | Sí |
| CODABAR | Sí | Sí | Sí, iOS 15.4+ |
| CODE_39 | Sí | Sí | Sí |
| CODE_93 | Sí | Sí | Sí |
| CODE_128 | Sí | Sí | Sí |
| EAN_8 | Sí | Sí | Sí |
| EAN_13 | Sí | Sí | Sí |
| ITF | Sí | Sí | Sí |
| UPC_A | Sí | Sí | Sí, normalizado desde el subconjunto EAN-13 en iOS |
| UPC_E | Sí | Sí | Sí |
Notas de normalización en iOS:
UPC_Ase normaliza desde el subconjuntoEAN_13cuando el valor empieza por0y la petición pidióUPC_AsinEAN_13.ITFse normaliza desdeinterleaved2of5eITF14.CODABARdepende del soporte runtime deAVFoundationen iOS 15.4+.
Contrato de resultado
Escaneo correcto:
{
"cancelled": false,
"text": "0123456789012",
"format": "EAN_13",
"nativeFormat": "EAN_13",
"engine": "google",
"platform": "android",
"rawBytesBase64": null,
"valueType": "PRODUCT",
"bounds": { "left": 0, "top": 0, "width": 100, "height": 50 },
"cornerPoints": [{ "x": 0, "y": 0 }],
"timestamp": 1713072000000
}La cancelación del usuario resuelve de forma normal:
{
"cancelled": true,
"text": null,
"format": null,
"nativeFormat": null,
"engine": "mlkit",
"platform": "android",
"rawBytesBase64": null,
"valueType": "UNKNOWN",
"bounds": null,
"cornerPoints": [],
"timestamp": 1713072000000
}Códigos de error
Códigos habituales:
INVALID_ARGUMENTINVALID_FORMATINVALID_ENGINESCAN_IN_PROGRESSUNSUPPORTEDGOOGLE_SCANNER_UNAVAILABLEINCOMPATIBLE_OPTIONSPERMISSION_DENIEDPERMISSION_RESTRICTEDCAMERA_UNAVAILABLETORCH_FAILEDUNSUPPORTED_FORMATSCAN_FAILEDRESULT_ENCODING_FAILEDUI_UNAVAILABLE
Compatibilidad con Firebasex
Validado contra [email protected].
Reglas de compatibilidad:
- No aplica el plugin
google-services. - No depende del SDK de Firebase.
- No usa artefactos obsoletos de Firebase ML Vision.
- No inyecta dependencias CocoaPods en iOS.
- No modifica variables de Firebasex ni la configuración de plugins de Gradle.
- Las dependencias Android se limitan a Google Code Scanner, CameraX, ML Kit Barcode Scanning y una pequeña dependencia runtime de Guava usada por el future del provider de CameraX.
Qué se validó:
cordova plugin adden una app Cordova Android limpia- compilación del APK debug Android
- compilación iOS para simulador
- instalación y
preparecon[email protected]
La smoke app de Firebasex se detiene a propósito en prepare, porque Firebasex necesita ficheros Firebase reales para completar un build nativo.
Licenciamiento y publicación
El código fuente del repositorio está licenciado bajo Apache License 2.0, lo que mantiene el paquete dentro de la familia de licencias usada por Apache Cordova y muchos plugins oficiales.
Matices importantes:
- Este repositorio es Apache-2.0.
- AndroidX y Guava son Apache-2.0.
Google Play Services Code ScanneryGoogle ML Kit Barcode Scanningse distribuyen bajo los ML Kit Terms of Service.- iOS usa frameworks del sistema de Apple y no añade pods de terceros.
En la práctica, el plugin puede publicarse en GitHub y npm bajo Apache-2.0, pero los equipos Android deben revisar igualmente los términos de ML Kit como parte de su proceso de compliance.
Consulta:
App de ejemplo
Hay una UI mínima en example-app/www.
Desarrollo
Tests:
npm testPruebas smoke:
npm run smoke:android
npm run smoke:ios
npm run smoke:firebasex
npm run smoke:all:latest-cli
npm run smoke:firebasex:latest-cliBenchmark de rendimiento:
npm run perf:benchEste benchmark mide la sobrecarga de la API JavaScript usando un bridge nativo mockeado y los hot paths de isSupported(), checkPermission(), scan() y la normalización de cancelación.
No mide el arranque físico de cámara, el throughput de análisis de frames en Android ni la latencia de cámara iOS en hardware concreto.
Verificación de empaquetado:
npm run pack:checkVerificación manual en dispositivo
npx -y [email protected] create native-scanner-smoke com.acme.nativescanner NativeScannerSmoke
cd native-scanner-smoke
npx -y [email protected] platform add [email protected]
npx -y [email protected] platform add [email protected]
npx -y [email protected] plugin add /absolute/path/to/plugin-folderDespués:
- copia la UI de ejemplo desde
example-app/www - ejecuta
npx -y [email protected] run android --device - o ejecuta
npx -y [email protected] run ios --device - verifica
isSupported(),requestPermission(),prewarm(),scan(), cancelación, linterna y al menos un escaneo QR y uno lineal
Checklist de publicación
- Ejecuta
npm test - Ejecuta
npm run smoke:android - Ejecuta
npm run smoke:ios - Ejecuta
npm run smoke:firebasex - Ejecuta
npm run smoke:all:latest-cli - Ejecuta
npm run smoke:firebasex:latest-cli - Ejecuta
npm run perf:bench - Ejecuta
npm run pack:check - Revisa
THIRD_PARTY_LICENSES.mdsi cambian las versiones de dependencias
Publicación en npm
El nombre del paquete sigue libre como paquete público sin scope. Antes de la primera publicación:
- Inicia sesión en npm:
npm login
npm whoami- Ejecuta las comprobaciones de release:
npm test
npm run smoke:all:latest-cli
npm run smoke:firebasex:latest-cli
npm run perf:bench
npm run pack:check- Publica la versión
1.0.0:
npm publish- Verifica el paquete:
npm view cordova-plugin-synapse-qr-scanner versionComando esperado de instalación:
cordova plugin add cordova-plugin-synapse-qr-scannerPara siguientes releases:
npm version patch
npm publishActualmente npm exige o bien 2FA activado en la cuenta o bien un token granular con permiso para publicar y bypass de 2FA habilitado.
Notas
prewarm()es best-effort:- Android intenta precalentar Google Code Scanner cuando es posible.
- iOS es un no-op seguro.
cancel()también es best-effort:- la activity ML Kit de Android y el escáner personalizado de iOS pueden cerrarse.
- con Google Code Scanner en Android es un no-op seguro porque la UI pertenece al sistema.
scanFromImage()se deja fuera de la v1 para mantener primero un camino de cámara en vivo estable.
