React Speech Recognition Hook
react-speech-recognition is an open-source React library that simplifies integrating browser-based speech recognition into React applications. It provides a `useSpeechRecognition` hook and a `SpeechRecognition` object, abstracting the complexities of the underlying Web Speech API to enable real-time transcription from a user's microphone. The library is currently stable at version 4.0.1, with releases occurring as needed to address bugs or add features. It is actively maintained. Key differentiators include its easy-to-use hook API, built-in handling for browser support detection, microphone access states, and a mechanism for defining voice commands. While it leverages the Web Speech API, which has best support in Chromium-based browsers, the library itself is designed for broad compatibility, recommending polyfills for wider cross-browser functionality.
Common errors
-
regeneratorRuntime is not defined
cause Missing `regenerator-runtime` polyfill, often in older environments or specific build setups (e.g., Next.js).fixInstall `regenerator-runtime` (`npm i --save regenerator-runtime`) and import it at the very top of your application's entry file (e.g., `import 'regenerator-runtime/runtime';` in `_app.js` for Next.js or `index.js` for other React apps). -
SpeechRecognition is not defined (or similar reference error)
cause Attempting to use `SpeechRecognition` object properties or methods without importing it as a default export, or in a browser that doesn't support the Web Speech API without a polyfill.fixEnsure you `import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';` and check `browserSupportsSpeechRecognition` before using the API. Consider applying a polyfill if cross-browser compatibility is needed. -
Microphone is blocked / Microphone access denied
cause The user has explicitly denied microphone access, or the application is running in an insecure context (HTTP) where microphone access is prohibited by the browser.fixDeploy your application over HTTPS. Ensure the UI clearly prompts the user for microphone permission and handles the `isMicrophoneAvailable` state, guiding users to enable permissions if denied.
Warnings
- gotcha The Web Speech API has limited cross-browser support, with Chrome providing the most robust experience. Other browsers (like Firefox, Safari) may require polyfills for full functionality or might not support it at all without extra configuration. Always check `browserSupportsSpeechRecognition`.
- breaking The `browserSupportsSpeechRecognition` state will now return `false` on browsers that do not support the APIs required for Speech Recognition polyfills (e.g., Internet Explorer), even if a polyfill is used. If a recognition implementation is already listening when a polyfill is applied, it will be disconnected and turned off to prevent multiple recognizers running.
- gotcha Microphone access requires user permission. The library now exposes `isMicrophoneAvailable` which becomes `false` if the user denies access. Attempting to start listening without prior user interaction (e.g., on component mount) may be blocked by browsers, resulting in errors or silent failure.
- gotcha Continuous listening (`continuous: true`) has varying levels of support and behavior across browsers. On Chrome for Android, it can lead to frequent microphone restarts and an annoying 'beeping' sound, which is an OS-level behavior not controllable by the browser.
- gotcha In production environments, the Web Speech API requires a secure context (HTTPS) to function correctly. It will not work over plain HTTP, even on local IP addresses, and microphone access will be blocked.
Install
-
npm install react-speech-recognition -
yarn add react-speech-recognition -
pnpm add react-speech-recognition
Imports
- useSpeechRecognition
import { useSpeechRecognition } from 'react-speech-recognition'; // Missing default export for SpeechRecognition objectimport SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'; - SpeechRecognition
import { SpeechRecognition } from 'react-speech-recognition'; // Incorrectly imported as a named exportimport SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'; - applyPolyfill
import { applyPolyfill } from 'react-speech-recognition';import SpeechRecognition from 'react-speech-recognition'; SpeechRecognition.applyPolyfill(MyCustomSpeechRecognition);
Quickstart
import React from 'react';
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
const Dictaphone = () => {
const commands = [
{
command: ['hello', 'hi'],
callback: () => alert('Hello there!')
},
{
command: 'open * website',
callback: (website) => {
window.open(`https://www.${website.split(' ').join('')}.com`);
}
},
{
command: ['clear', 'reset'],
callback: () => resetTranscript()
}
];
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition,
isMicrophoneAvailable,
finalTranscript
} = useSpeechRecognition({
commands,
continuous: false // Set to true for continuous listening, but be aware of browser quirks
});
if (!browserSupportsSpeechRecognition) {
return <span>Browser doesn't support speech recognition. Consider a polyfill.</span>;
}
if (!isMicrophoneAvailable) {
return <span>Microphone is not available or permission was denied.</span>;
}
return (
<div>
<p>Microphone: {listening ? 'ON' : 'OFF'}</p>
<button onClick={() => SpeechRecognition.startListening({ language: 'en-US' })}>Start</button>
<button onClick={SpeechRecognition.stopListening}>Stop</button>
<button onClick={resetTranscript}>Reset Transcript</button>
<p>Transcript: {transcript}</p>
<p>Final Transcript: {finalTranscript}</p>
</div>
);
};
export default Dictaphone;