Fast native WebRTC voice activity detection for React Native, built with Nitro Modules.
react-native-nitro-webrtc-vad runs the WebRTC VAD engine in native C/C++ code and emits simple speech state transitions to JavaScript.
- Native WebRTC VAD for iOS and Android
- Nitro Modules JSI API
- Built-in microphone capture with
speechStartandspeechEndevents - Direct PCM16 frame classification with
processFrame - No WebRTC checkout,
depot_tools,gn, orninjasetup required
- React Native 0.76 or newer
- Node.js 18 or newer
react-native-nitro-modules- Android minSdkVersion 23 or newer
- iOS through the React Native CocoaPods toolchain
Expo apps must use a prebuild/dev-client native build. Expo Go is not supported because this package contains native C/C++ code.
bun add react-native-nitro-webrtc-vad react-native-nitro-modulesnpm install react-native-nitro-webrtc-vad react-native-nitro-modulesyarn add react-native-nitro-webrtc-vad react-native-nitro-modulesFor iOS, install pods after adding the package:
cd ios && pod installFor Expo prebuild/dev-client apps:
npx expo prebuildAndroid includes RECORD_AUDIO in the library manifest, but your app still needs to request microphone permission at runtime before calling start().
import { PermissionsAndroid, Platform } from 'react-native'
async function requestMicrophonePermission() {
if (Platform.OS !== 'android') {
return true
}
const result = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO
)
return result === PermissionsAndroid.RESULTS.GRANTED
}On iOS, add NSMicrophoneUsageDescription to your app's Info.plist.
<key>NSMicrophoneUsageDescription</key>
<string>This app uses the microphone to detect voice activity.</string>import { NitroWebrtcVad, type VadEventType } from 'react-native-nitro-webrtc-vad'
NitroWebrtcVad.setListener((eventType: VadEventType, timestampMs: number) => {
if (eventType === 'speechStart') {
console.log('Speech started', timestampMs)
}
if (eventType === 'speechEnd') {
console.log('Speech ended', timestampMs)
}
})
NitroWebrtcVad.start({
mode: 2,
sampleRate: 16000,
frameMs: 20,
speechStartFrames: 3,
speechEndFrames: 8,
})
// Later:
NitroWebrtcVad.stop()
NitroWebrtcVad.clearListener()Use processFrame() when you already have mono PCM16 audio frames and want to classify them yourself.
NitroWebrtcVad.start({ sampleRate: 16000, frameMs: 20 })
const frame = new Int16Array(320)
const isSpeech = NitroWebrtcVad.processFrame(frame.buffer)The frame byte length must match the configured sampleRate and frameMs.
Starts native VAD processing and microphone capture.
Options:
mode: WebRTC VAD aggressiveness from0to3. Higher values are more aggressive. Default:2.sampleRate: Input sample rate. Supported WebRTC VAD rates include8000,16000,32000, and48000. Default:16000.frameMs: Frame duration. Must be10,20, or30. Default:20.speechStartFrames: Consecutive speech frames required beforespeechStart. Default:3.speechEndFrames: Consecutive non-speech frames required beforespeechEnd. Default:8.
Stops native VAD processing and microphone capture.
Registers a listener for VAD state changes.
type VadEventType = 'speechStart' | 'speechEnd'
type VadListener = (eventType: VadEventType, timestampMs: number) => voidRemoves the current listener.
Processes a single mono PCM16 ArrayBuffer and returns true for speech or false for non-speech.
- Call
start()beforeprocessFrame(). - Call
stop()when your screen or recording session ends. start()throws if VAD is already running.processFrame()throws if the frame size does not match the configured VAD frame size.
This package vendors the small WebRTC VAD source needed for native builds. Consumers should not need to install WebRTC-specific build tools. See Consumer Build Contract for details.
MIT