capacitor-wake-word
v0.1.2
Published
On-device custom wake word, hotword, and keyword detection for Capacitor and Cordova on Android and iOS.
Maintainers
Readme
Capacitor Wake Word Detection Plugin for Android and iOS
capacitor-wake-word is an on-device wake word detection plugin for Capacitor and
Cordova apps on Android and iOS, by DaVoice.io. It is
used for custom wake words, hotword detection, keyword spotting, trigger-word
detection, phrase recognition, and voice-command activation without streaming
microphone audio through the JavaScript WebView.
A wake word is a word or phrase such as “Hey Siri” or “OK Google” that activates
an app. When the native DaVoice detector recognizes a configured phrase, this
plugin sends a keywordDetected event to the Capacitor or Cordova application.
Release status: version
0.1.2is published. It uses.dmmodel resources on both platforms, includinglayer1.dm, and contains no loose ONNX model files. Capacitor and Cordova builds and native detector create/destroy smoke tests pass with the iOS Layer1 implementation. A licensed, spoken-wake-word physical-device test remains recommended for production integration.
Features
- Offline, on-device wake word and keyword detection.
- One Capacitor npm package for Android and iOS through Capacitor's Cordova compatibility layer.
- Single-model and multi-model detection instances.
- Custom wake word and voice-command models supplied by DaVoice.
- Promise-based JavaScript API with TypeScript declarations.
- Instance-scoped
keywordDetectedevents. - Microphone permission, pause/resume, VAD, recording, audio-routing, and lifecycle cleanup APIs.
- Native inference: microphone audio is not sent through the WebView.
| Framework | Android | iOS | | --- | --- | --- | | Cordova | Supported | Supported | | Capacitor 8 | Supported through Cordova compatibility | Supported through Cordova compatibility with CocoaPods |
Capacitor and Cordova API
The API intentionally follows Capacitor conventions: every method takes one
options object, resolves to one result object, and uses string instanceId
values instead of returning framework-owned native objects. Event listeners
return an async, idempotent remove() handle.
This is a Capacitor package implemented through Capacitor's supported Cordova compatibility layer. The native detector logic is kept outside the Cordova adapter so a future first-class Capacitor adapter can reuse it without rewriting detector behavior.
Installation
Cordova:
cordova plugin add capacitor-wake-word \
--variable MICROPHONE_USAGE_DESCRIPTION="Use the microphone for on-device wake word detection."Capacitor Android uses the normal compatibility flow:
npm install capacitor-wake-word
npx cap sync androidFor a new Capacitor iOS project, select CocoaPods when adding iOS:
npx cap add ios --packagemanager CocoaPods
npx cap sync iosCapacitor's Swift Package Manager mode is not currently supported because the
unchanged iOS detector depends on onnxruntime-objc ~> 1.20.0 through
CocoaPods. Existing Capacitor iOS projects therefore also need to use the
CocoaPods package manager. Capacitor 8 itself requires Node.js 22 or newer, and
its current Android toolchain requires Java 21.
Basic use
Wait for Cordova's deviceready event before calling the plugin:
document.addEventListener('deviceready', async () => {
const permissions = await DaVoiceWakeWord.requestPermissions({});
if (permissions.microphone !== 'granted') return;
const listener = await DaVoiceWakeWord.addListener(
'keywordDetected',
event => console.log('Wake word detected', event)
);
await DaVoiceWakeWord.create({
instanceId: 'primary',
modelName: 'hey_lookdeep.dm',
threshold: 0.99,
bufferCount: 2
});
const license = await DaVoiceWakeWord.setLicense({
instanceId: 'primary',
license: 'YOUR_DAVOICE_LICENSE'
});
if (!license.licensed) throw new Error('DaVoice license was rejected');
await DaVoiceWakeWord.start({ instanceId: 'primary', threshold: 0.99 });
// Later:
await DaVoiceWakeWord.stop({ instanceId: 'primary' });
await DaVoiceWakeWord.destroy({ instanceId: 'primary' });
await listener.remove();
});The recommended starting values are threshold: 0.99 and bufferCount: 2.
They are also the create() defaults when those options are omitted. Android's
start() threshold also defaults to 0.99; iOS applies the threshold when the
detector is created. Thresholds can be tuned for a particular custom model and
acoustic environment.
For iOS, start() defaults to the same audio-session behavior as the current
React Native wrapper: noExternalActivation: true, duckOthers: false,
mixWithOthers: true, and defaultToSpeaker: true. Pass explicit values when
the host app owns the shared audio session.
Main API
| Method | Purpose |
| --- | --- |
| create() / createMulti() | Create a single-model or multi-model detector instance. |
| setLicense() | Apply the DaVoice license to an instance. |
| start() / stop() | Start or stop native wake word detection. |
| pause() / resume() | Temporarily pause and resume an instance. |
| replaceModel() | Replace an instance's wake word model. |
| addListener('keywordDetected', ...) | Receive wake word or phrase detection events. |
| checkPermissions() / requestPermissions() | Check or request microphone access. |
| setVadParameters() / startVad() / stopVad() | Configure and control voice activity detection. |
| setAudioRoutingConfig() | Configure supported native audio-routing behavior. |
| destroy() / destroyAll() | Release native detector and microphone resources. |
See types/index.d.ts for the complete typed contract,
including recording helpers and Android foreground-service methods.
Local integration fixture
The tracked example/ Cordova application and example-capacitor/ application
are Android/iOS integration fixtures. From the package root:
Standalone examples that install the published npm package are available for Cordova and Capacitor.
npm install
npm run fixture:prepare
npm run fixture:build:android
npm run fixture:build:iosGenerated fixture dependencies, platforms, plugins, builds, and screenshots are
ignored. The checked-in example/config.xml, example/package.json, and
example/www files are the reproducible inputs.
Android's Cordova build requires Gradle to be available on PATH for initial
wrapper creation. The generated wrapper then uses the Cordova-selected Gradle
distribution.
Preparing a package release
Use the local release helper to keep the npm and Cordova plugin versions in
sync, run validation, and create the capacitor-wake-word tarball:
./upgrade_package.sh # patch version bump, check, and pack
./upgrade_package.sh --no-bump # check and pack the current versionPublishing requires the explicit --publish flag. It remains blocked while
package.json contains "private": true. The canonical repository files stay
Cordova-branded; the helper creates and validates the Capacitor-branded variant
in a temporary directory, publishes both names, and safely removes that staging
directory on exit. Existing versions are skipped so a partially completed dual
release can be retried.
iOS microphone usage text
The plugin provides a default microphone usage description. An application can override it while adding the plugin:
cordova plugin add capacitor-wake-word \
--variable MICROPHONE_USAGE_DESCRIPTION="Use the microphone to listen for your chosen wake word."Included models
The package includes only .dm model resources on both platforms:
hey_lookdeep.dm, need_help_now.dm, and required layer1.dm. The iOS
XCFramework and Android AAR resolve the shared first-stage models from
layer1.dm. No loose ONNX model files are distributed. See ARTIFACTS.md for
exact provenance, sizes, and SHA-256 checksums.
Custom wake words and voice commands
DaVoice can generate a model for a custom activation phrase or voice command.
For example, a phrase such as “Hey Sky” is represented by a platform model that
the application passes to create() or createMulti().
Contact [email protected] for custom wake word models, licensing, and deployment
support. Wake-word models use the native .dm format on Android and iOS.
FAQ
Does Cordova support wake word detection?
Yes. capacitor-wake-word runs the DaVoice detector natively on Android and iOS
and delivers detections to JavaScript as keywordDetected events.
Can I use the same wake word package with Capacitor?
Yes. The same npm package is tested through Capacitor's Cordova compatibility
layer. Capacitor iOS currently requires CocoaPods because the native iOS
framework depends on the onnxruntime-objc pod.
Is wake word detection offline?
Detection and microphone processing run on the device. The wrapper does not stream microphone audio through the WebView. A valid DaVoice license is still required by the native detector.
Can one app detect multiple wake words?
Yes. Use createMulti() with matching model, threshold, buffer-count, and
callback-cooldown arrays.
What are hotwords, trigger words, and keyword spotting?
They are common names for recognizing a configured word or phrase in audio. “Wake word” usually describes a phrase that activates an app, while the same on-device detection mechanism can also trigger a specific voice-command action.
