Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 1,000,000+ packages pre-installed, including react-native-spokestack with all npm packages installed. Try it out:

require("react-native/package.json"); // react-native is a peer dependency. var reactNativeSpokestack = require("react-native-spokestack")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

react-native-spokestack v3.2.14

React Native wrapper for Spokestack


React Native wrapper for the Spokestack speech activity detection/automated speech recognition project.

## Table of Contents * [Getting started](#getting-started) * [Usage](#usage) * [API](#api) * [Gotchas](#gotchas) * [Release](#release) * [License](#license)

Getting started

$ npm install react-native-spokestack --save

  • React Native: 0.60.0+
  • Android: Android SDK 26+
  • iOS: iOS 13+

(Mostly) automatic installation


$ react-native link react-native-spokestack



  1. iOS 13, Swift 5.0


  1. Edit YOUR_PROJECT's Podfile and add the following contents:
platform :ios, '13.0'

target 'YOUR_PROJECT' do


  pod 'RNSpokestack', :path => '../node_modules/react-native-spokestack'


  1. pod install

RN 0.58+ notes

  • In the Podfile remove jschelpers from the React subspec. (reference)
  • If using Rn 0.58.0 - 0.58.4, an additional header path needs to be added to the jsiexecutor subspec in node_modules/react-native/React.podspec. You may use patch-package as a solution. This issue is was addressed and fixed in RN 0.58.5
  • Remove all lib* files from Link Binary with Libraries under your project target in xCode. This prevents dueling installations of React.

...thus we need to ensure that they reference the same React Native library which you link to from the outer project.

Manual installation


  1. Open up android/app/src/main/java/[...]/ (could also be called or similar)
  • Add import io.spokestack.RNSpokestack.RNSpokestackPackage; to the imports at the top of the file
  • Add new RNSpokestackPackage() to the list returned by the getPackages() method
  1. Append the following lines to android/settings.gradle:
    include ':react-native-spokestack'
    project(':react-native-spokestack').projectDir = new File(rootProject.projectDir,    '../node_modules/react-native-spokestack/android')
  2. Insert the following lines inside the dependencies block in android/app/build.gradle:
      implementation project(':react-native-spokestack')

iOS (not using CocoaPods)

  • Currently only buildable on an amd_64 target

  • Drag the RNSpokestack.xcodeproj from the react-native-spokestack/ios folder to the Libraries group on Xcode in your poject.

  • Click on your main project file (the one that represents the .xcodeproj) select Build Phases and drag the static library, libRNSpokestack.a, from the Libraries/RNSpokestack.xcodeproj/Products folder to Link Binary With Libraries

Link the necessary libraries:
  • Project Build Phases

    • Link Binary with Libraries:

      • /node_modules/react-native-spokestack/Frameworks
      • AVFoundation
      • SpokeStack.framework
    • Copy Bundle Resources:

      • gRCPCertificate.bundle
  • General

    • Always Embed Swift Standard Libraries: Yes
    • Embedded Binaries:
      • /node_modules/react-native-spokestack/Frameworks
      • SpokeStack.framework
      • Linked Frameworks and Binaries:
      • /node_modules/react-native-spokestack/Frameworks
      • SpokeStack.framework

Android Support


Make sure the Google repo is listed first

buildscripts {
    repositories {
      maven { url '' }

      repositories {
        maven { url '' }


android {
packagingOptions {
exclude ''


// for wakeword & ASR
<uses-permission android:name="android.permission.RECORD_AUDIO" />
// for TTS
<uses-permission android:name="android.permission.INTERNET" />



The example below uses the system-provided AndroidSpeechRecognizer as the default since it's free to use. It's not available on 100% of devices, though; see our ASR documentation for more information. If you use a different ASR provider, you'll also need to change the input line to:

input: "",

import Spokestack from "react-native-spokestack";

// initialize the Spokestack pipeline.
// Spokestack configuration has five top-level keys: 'input', 'stages', and 'properties' for the speech pipeline, 'tts' for text to speech, and 'nlu' for natural language recognition. Keys for asr, tts, and nlu may be omitted if your app does not require them.
// This example configures a voice-triggered speech recongnizer
// For additional examples, see
  input: "", // provides audio input into the pipeline
  stages: [
    "io.spokestack.spokestack.webrtc.VoiceActivityDetector", // voice activity detection
    'io.spokestack.spokestack.webrtc.VoiceActivityTrigger', // voice activity detection triggers speech recognition
    'io.spokestack.spokestack.ActivationTimeout', // speech recognition times out after a configurable interval when voice is no longer detected
      '' // one of the three supported speech recognition services
    // ""
    // ''
  properties: {
    "locale": "en-US",
    'agc-compression-gain-db': 15,
    "google-credentials": YOUR_GOOGLE_VOICE_CREDENTIALS, // only set if using `GoogleSpeechRecognizer` stage above
    "trace-level": Spokestack.TraceLevel.DEBUG // configurable logging level
  tts: {
    'ttsServiceClass': 'io.spokestack.spokestack.tts.SpokestackTTSService',
    // TTS API account properties. Only set these if you have a Spokestack account.
    'spokestack-id': 'f0bc990c-e9db-4a0c-a2b1-6a6395a3d97e', // your Spokestack API ID
    'spokestack-secret': '5BD5483F573D691A15CFA493C1782F451D4BD666E39A9E7B2EBE287E6A72C6B6' // your Spokestack API secret
  nlu: {
    // NLU settings. Only set these if you are calling `Spokestack.classify`.
    'nlu-model-path': YOUR_NLU_MODEL_PATH, // string filesystem path to nlu model
    'nlu-metadata-path': YOUR_NLU_METADATA_PATH, // string filesystem path to nlu metadata
    'wordpiece-vocab-path': YOUR_NLU_VOCABULARY_PATH // string filesystem path to nlu vocab

// Speech Pipeline

// Start and stop the speech pipeline. All methods can be called repeatedly.
Spokestack.start(); // start speech pipeline. can only start after initialize is called.
Spokestack.stop(); // stop speech pipeline
Spokestack.activate(); // manually activate the speech pipeline. The speech pipeline is now actively listening for speech to recognize.
Spokestack.deactivate(); // manually deactivate the speech pipeline. The speech pipeline is now passively waiting for an activation trigger.\
// Binding to speech pipeline events
const logEvent = e => console.log(e);
Spokestack.onActivate = logEvent;
Spokestack.onDeactivate = logEvent;
Spokestack.onError = e => {
Spokestack.onTrace = e => { // subscribe to tracing events according to the trace-level property
Spokestack.onRecognize = e => {
  console.log(e.transcript) // "Hello Spokestack"

// NLU and TTS

// Classify the intent and slot of the transcript
Spokestack.classify(e.transcript, {})
// Get a URL to a real-time synthesize
Spokestack.synthesize({'input': e.transcript, 'format': Spokestack.TTSFormat.TEXT, 'voice': 'demo-male'})
// Receive the transcript classifcation result
Spokestack.onClassification = e => {
// Receive the real-time transcript synthesis result
Spokestack.onSuccess = e => {
  console.log(e.url) //



Method NameDescriptionMethod ValuesOS
Spokestack.initialize()Initialize the speech pipeline; required for all other methodsAndroid, iOS
Spokestack.start()Starts the speech pipeline. The speech pipeline starts in the deactivate state.Android, iOS
Spokestack.stop()Stops the speech pipelineAndroid, iOS
Spokestack.activate()Manually activate the speech pipelineAndroid, iOS
Spokestack.deactivate()Manually deactivate the speech pipelineAndroid, iOS
Spokestack.synthesize({'input': string, 'format': int, 'voice': string})Request a URL to a audio file of the specified voice speaking the inputformat [0: text, 1: ssml, 2: speechmarkdown], voice ["demo-male"]iOS, Android
Spokestack.classify(utterance: string, {})Classify the utterance with an intent/slot natural language understanding modelutterance: string, context: dictionary (currently unused, can be empty)iOS, Android


Event NamePropertyDescriptionOS
onActivate(event)nullInvoked when the speech pipeline is activated, which enables the speech recognizer and begins a new dialogue sessionAndroid, iOS
onDeactivate(event)nullInvoked when the speech pipeline has been deactivatedAndroid, iOS
onStart(event)nullInvoked when the speech pipeline is startedAndroid, iOS
onStop(event)nullInvoked when the speech pipeline has been stoppedAndroid, iOS
onRecognize(event)transcript:stringInvoked when speech has been recognizedAndroid, iOS
onTimeout(event)nullInvoked when no speech has been detected for wake-active-max after activationAndroid, iOS
onTrace(event)message:stringInvoked when a trace message become availableAndroid
onError(event)error:stringInvoked upon an error in the speech pipeline executionAndroid, iOS
onSuccess(ttsEvent)url:stringInvoked upon a successful TTS synthesis requestiOS
onFailure(ttsEvent)error:stringInvoked upon a failed TTS synthesis requestiOS
onClassification(nluEvent)result:dictionaryInvoked upon a successful NLU utterance classificationiOS











  • Requires Android SDK 26 level support
  • Requires Gradle 3.0.1+ (classpath '' in root build.gradle dependencies)
  • Add app setting for microphone permission


  • Add app setting for microphone permission (NSMicrophoneUsageDescription) and speech recognition (NSSpeechRecognitionUsageDescription)
  • Spokestack on iOS does not manage AudioSession settings. The client app is required to implement whatever AudioSession category and options are necessary. At minimum, the session category should allow for recording, eg AVAudioSessionCategoryRecord or AVAudioSessionCategoryPlayAndRecord. A simple AudioSession setting, suitable for insertion in AppDelegate.m, could be:
  [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord mode:AVAudioSessionModeDefault options:AVAudioSessionCategoryOptionDefaultToSpeaker  error:nil];
  [[AVAudioSession sharedInstance] setActive:YES error:nil];


  1. Ensure that CocoaPods has been installed via gem, not via brew
  2. Increment version in package.json
  3. git commit -a -m 'YOUR_COMMIT_MESSAGE' && git tag YOUR_VERSION && git push --origin
  4. pod spec lint --use-libraries --allow-warnings --use-modular-headers, which should pass all but one checks (expect ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use--verbosefor more information.)
  5. edit /Library/Ruby/Gems/YOUR_RUBY_VERSION/gems/cocoapods-trunk-YOUR_COCOAPODS_VERSION/lib/pod/command/trunk/push.rb, comment out validate_podspec_files (*
  6. pod trunk register YOUR_EMAIL --description='release YOUR_PODSPEC_VERSION'
  7. npm publish to release on NPM
  8. pod trunk push --use-libraries --allow-warnings --use-modular-headers
  • Since RNSpokestack iOS requires React Native headers, but does not include any React Native dependencies, it will not compile by itself, needing a client library that does include the React Native dependency.


Copyright 2020 Spokestack, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free