---
title: Exploring the Capacitor Speech Recognition API
description: "Practical guide to the Capacitor Speech Recognition API: integrate on-device voice transcription into Ionic and Capacitor apps."
date: 
  created: 2025-07-16
  updated: 2026-07-17
authors:
  - robingenz
categories:
  - Capacitor
  - Guides
  - SDKs
links:
  - Capacitor Speech Recognition: sdks/capacitor/speech-recognition.md
faq: true
---

# Exploring the Capacitor Speech Recognition API

The [Capacitor Speech Recognition plugin](../../sdks/capacitor/speech-recognition.md) from Capawesome adds voice commands and dictation to Ionic and Capacitor applications. It converts speech to text in real time on Android, iOS, and Web through a single API, so you don't write against each platform's own speech recognition implementation.

<!-- more -->

## Installation

To install the Capacitor Speech Recognition plugin, please refer to the [Installation](../../sdks/capacitor/speech-recognition.md/#installation) section in the plugin documentation.

## Usage

Let's explore the key features of the Capacitor Speech Recognition API and how to implement them effectively in your Ionic applications.

### Permission Handling

Before implementing speech recognition, your application needs permission to access the microphone and the speech recognition service. The Capacitor Speech Recognition API provides the [`checkPermissions(...)`](../../sdks/capacitor/speech-recognition.md#checkpermissions) and [`requestPermissions(...)`](../../sdks/capacitor/speech-recognition.md#requestpermissions) methods for this purpose:

```ts
import { SpeechRecognition } from '@capawesome-team/capacitor-speech-recognition';

const checkPermissions = async () => {
  const permissions = await SpeechRecognition.checkPermissions();
  
  if (permissions.speechRecognition !== 'granted' || permissions.microphone !== 'granted') {
    console.log('Permissions not granted, requesting...');
    await requestPermissions();
  }
};

const requestPermissions = async () => {
  const permissions = await SpeechRecognition.requestPermissions();
  
  if (permissions.speechRecognition !== 'granted') {
    alert('Speech recognition permission is required to use this feature.');
  }
  
  if (permissions.microphone !== 'granted') {
    alert('Microphone permission is required to capture audio.');
  }
};
```

Always verify permissions before starting speech recognition to prevent permission-related errors.

### Start Listening

To begin capturing and recognizing speech, use the [`startListening(...)`](../../sdks/capacitor/speech-recognition.md#startlistening) method. This method allows you to configure various options for the recognition session:

```ts
const startListening = async () => {
  try {
    // Add all necessary event listeners
    SpeechRecognition.addListener('start', () => {
      console.log('Speech recognition started');
    });
    SpeechRecognition.addListener('speechStart', () => {
      console.log('User started speaking');
    });
    SpeechRecognition.addListener('speechEnd', () => {
      console.log('User stopped speaking');
    });
    SpeechRecognition.addListener('partialResult', (event) => {
      console.log('Partial result:', event.partialResult);
    });
    SpeechRecognition.addListener('result', (event) => {
      console.log('Final result:', event.result);
    });
    SpeechRecognition.addListener('end', () => {
      console.log('Speech recognition ended');
    });
    SpeechRecognition.addListener('error', (event) => {
      console.error('Speech recognition error:', event.message);
    });
    
    // Start listening for speech input
    await SpeechRecognition.startListening({
      language: 'en-US',
      silenceThreshold: 2000,
      partialResultsEnabled: true,
      contextualStrings: ['Capacitor', 'Ionic', 'Angular']
    });
    
    console.log('Speech recognition started successfully');
  } catch (error) {
    console.error('Failed to start speech recognition:', error);
  }
};
```

The `startListening(...)` method accepts several configuration options including language selection, silence detection thresholds, and contextual strings that help improve recognition accuracy for domain-specific vocabulary. Make sure to adjust these parameters based on your application's requirements. Also, ensure that you add all necessary event listeners before calling `startListening(...)` to handle various speech recognition events effectively. The following events are available:

- **`start`**: Triggered when speech recognition begins - use this to update your UI to show that the system is ready to listen.
- **`end`**: Triggered when the recognition session concludes - use it to return your UI to an idle state.
- **`speechStart`**: Fired when the user begins speaking - use it to show that speech is being detected.
- **`speechEnd`**: Called when the user stops speaking - useful for indicating that the system is processing the captured audio.
- **`partialResult`**: Provides interim transcription results while the user is speaking - use it to display the transcript as it arrives.
- **`result`**: Delivers the final transcribed text when recognition completes - this is where you'll process the user's speech input.
- **`error`**: Fired when recognition errors occur - use it to handle network issues, permission problems, or recognition failures.

### Stop Listening

To manually end the speech recognition session, use the [`stopListening(...)`](../../sdks/capacitor/speech-recognition.md#stoplistening) method:

```ts
const stopListening = async () => {
  try {
    await SpeechRecognition.stopListening();
    console.log('Speech recognition stopped');
  } catch (error) {
    console.error('Failed to stop speech recognition:', error);
  }
};
```

The `stopListening(...)` method only needs to be called if you want to manually stop the recognition session. Otherwise, the speech recognition will automatically stop based on the configured timeout or when silence is detected for the specified duration.

## Best Practices

When implementing speech recognition with the Capacitor Speech Recognition API, consider these best practices:

1. **Implement comprehensive error handling**: Always handle the `error` event to manage network issues, audio capture problems, and recognition failures gracefully. Provide clear feedback to users about what went wrong and how they can resolve the issue.

2. **Optimize silence detection**: Configure the `silenceThreshold` parameter based on your application's use case. For conversational interfaces, use shorter thresholds (1-2 seconds) to maintain responsiveness, while dictation applications may benefit from longer thresholds (5-10 seconds) to accommodate natural pauses in speech.

3. **Provide visual feedback**: Use the various event listeners (`start`, `speechStart`, `speechEnd`, `end`) to update your UI and provide clear visual indicators of the recognition state. Show users when the system is listening, processing, or idle.

## FAQ

### Does `silenceThreshold` work reliably on every platform, including a very high value for continuous listening?

Not fully reliably, and it's Android (SDK 33+) and iOS only. There's no web equivalent. Even on supported platforms, this option depends on the underlying OS speech recognition service, so behavior can vary by device, and setting an extremely high value to try to force continuous listening is documented not to work. Treat it as a hint to the platform, not a guaranteed timer.

### Can I force speech recognition to run entirely on-device, without sending audio to a server?

Yes, on Android (SDK 33+) and iOS, using `requireOnDeviceRecognition: true`. If the on-device model isn't available on that device, the call fails with an error rather than silently falling back to server-based recognition — so you need to handle that failure case if privacy-sensitive, offline-capable transcription is a hard requirement for your feature.

### What's the difference between `requireOnDeviceRecognition` and `useSpeechTranscriber`?

`useSpeechTranscriber` is a separate, iOS 26+-only option that opts into Apple's newer `SpeechTranscriber` API. It implies on-device processing on its own (you don't need to also set `requireOnDeviceRecognition`), and its specific benefit is avoiding the "Speech data will be sent to Apple" permission dialog entirely, requiring only microphone permission instead.

### Does `contextualStrings` help recognition accuracy on every platform?

No — it's Android (SDK 33+) and iOS only, with no web support. On unsupported OS versions, passing domain-specific vocabulary this way has no effect, so don't rely on it as your only accuracy strategy if you need to support older Android devices.

### Will `enableFormatting` reliably add punctuation to my transcripts?

Only somewhat, and only on Android (SDK 33+) and iOS 16+. The plugin's own documentation is explicit that on Android, this option doesn't work reliably since behavior varies by device and TTS engine — so don't build a feature that assumes punctuation will always be present in Android transcripts.

## Conclusion

For a new integration, register your listeners before you call `startListening(...)`, and set `silenceThreshold` to match your use case: 1-2 seconds for conversational interfaces, 5-10 seconds for dictation. Set `requireOnDeviceRecognition: true` only if you also handle the error that the plugin throws when no on-device model is available on the device.

Transcription is often just the input half of a voice feature. To process the recognized text with an on-device model, pair this plugin with the [Capacitor LLM plugin](./announcing-the-capacitor-llm-plugin.md), or with [Apple Intelligence on iOS](./how-to-use-apple-intelligence-in-a-capacitor-app.md).

To stay updated with the latest updates, features, and news about the Capawesome, Capacitor, and Ionic ecosystem, subscribe to the [Capawesome newsletter](/newsletter/){:target="_blank"} and follow us on [X (formerly Twitter)](https://x.com/capawesomeio){:target="_blank"}.

If you have any questions or need assistance with the Capacitor Speech Recognition plugin, feel free to reach out to the Capawesome team. We're here to help you add voice recognition to your Ionic applications.
