Gathering detailed insights and metrics for react-native-audio-recorder-player
Gathering detailed insights and metrics for react-native-audio-recorder-player
Gathering detailed insights and metrics for react-native-audio-recorder-player
Gathering detailed insights and metrics for react-native-audio-recorder-player
@react-native-oh-tpl/react-native-audio-recorder-player
React Native Audio Recorder and Player.
react-native-audio-recorder-player-adalo
React Native Audio Recorder and Player.
komodaa-react-native-audio-recorder-player
React Native Audio Recorder and Player.
@matthiasn/react-native-audio-recorder-player
React Native Audio Recorder and Player.
react-native native module for audio recorder and player with nitromodule!
npm install react-native-audio-recorder-player
Typescript
Module System
Node Version
NPM Version
TypeScript (37.84%)
Swift (29.37%)
Kotlin (23.73%)
Ruby (4.31%)
JavaScript (3.91%)
CMake (0.65%)
C++ (0.18%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
782 Stars
469 Commits
231 Forks
8 Watchers
2 Branches
53 Contributors
Updated on Jul 18, 2025
Latest Version
4.1.4
Package Id
react-native-audio-recorder-player@4.1.4
Unpacked Size
334.66 kB
Size
53.94 kB
File Count
104
NPM Version
10.2.4
Node Version
20.11.1
Published on
Jul 16, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
3
26
🎉 Version 4.1.0 Released with NitroModule Support!
⚠️ Important: Version 4.0.0 had issues with Nitro integration. Please install version 4.1.0 or later.
🔴 Critical for v4.x: Recording operations now run in background threads. You MUST implement loading states to handle the async delays, or your UI may appear unresponsive. See Component Examples for proper implementation.
This is a high-performance React Native module for audio recording and playback, now powered by NitroModules for direct native module access without bridge overhead. The library provides simple recorder and player functionalities for both Android and iOS platforms with full TypeScript support and type safety.
Version 4.0.0 introduces a complete rewrite using NitroModules, offering:
If you're upgrading from version 3.x or earlier, please refer to our Migration Guide for detailed instructions and breaking changes.
⚠️ Important: Install version 4.1.0 or later to avoid Nitro integration issues from version 4.0.0.
Install packages:
1yarn add react-native-audio-recorder-player react-native-nitro-modules
Or using npm:
1npm install react-native-audio-recorder-player react-native-nitro-modules
After installing the packages, follow these steps:
iOS Setup:
1cd ios && pod install
Android Setup: No additional steps required. The module uses autolinking.
Note: The
nitro-codegen
command is already run during the library's build process. You don't need to run it in your application.
Microphone Permission: Add to your Info.plist
:
1<key>NSMicrophoneUsageDescription</key> 2<string>Give $(PRODUCT_NAME) permission to use your microphone. Your record wont be shared without your permission.</string>
Minimum iOS Version: Ensure your minimum deployment target is iOS 13.0 or higher in your Podfile
:
1platform :ios, '13.0'
On Android you need to add permissions to AndroidManifest.xml
:
1<uses-permission android:name="android.permission.INTERNET" /> 2<uses-permission android:name="android.permission.RECORD_AUDIO" /> 3<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 4<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Also, android above Marshmallow
needs runtime permission to record audio. Below are two approaches:
Minimal Approach (Recommended for Android 13+):
1if (Platform.OS === 'android') { 2 try { 3 const granted = await PermissionsAndroid.request( 4 PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, 5 { 6 title: 'Audio Recording Permission', 7 message: 'This app needs access to your microphone to record audio.', 8 buttonNeutral: 'Ask Me Later', 9 buttonNegative: 'Cancel', 10 buttonPositive: 'OK', 11 } 12 ); 13 14 if (granted === PermissionsAndroid.RESULTS.GRANTED) { 15 console.log('Recording permission granted'); 16 } else { 17 console.log('Recording permission denied'); 18 return; 19 } 20 } catch (err) { 21 console.warn(err); 22 return; 23 } 24}
Full Permissions Approach (For older Android versions):
1if (Platform.OS === 'android') { 2 try { 3 const grants = await PermissionsAndroid.requestMultiple([ 4 PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, 5 PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE, 6 PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, 7 ]); 8 9 if ( 10 grants['android.permission.WRITE_EXTERNAL_STORAGE'] === 11 PermissionsAndroid.RESULTS.GRANTED && 12 grants['android.permission.READ_EXTERNAL_STORAGE'] === 13 PermissionsAndroid.RESULTS.GRANTED && 14 grants['android.permission.RECORD_AUDIO'] === 15 PermissionsAndroid.RESULTS.GRANTED 16 ) { 17 console.log('All permissions granted'); 18 } else { 19 console.log('All required permissions not granted'); 20 return; 21 } 22 } catch (err) { 23 console.warn(err); 24 return; 25 } 26}
Method | Param | Return | Description |
---|---|---|---|
mmss | number seconds | string | Convert seconds to minute:second string |
mmssss | number seconds | string | Convert seconds to minute:second:millisecond string |
setSubscriptionDuration | number duration | void | Set callback interval in ms (default 500ms) |
startRecorder | string? uri, AudioSet? audioSet, | Promise<string> | Start recording with optional path and audio settings |
boolean? meteringEnabled | |||
pauseRecorder | Promise<string> | Pause recording | |
resumeRecorder | Promise<string> | Resume recording | |
stopRecorder | Promise<string> | Stop recording and return file path | |
startPlayer | string? uri, Record<string, string>? headers | Promise<string> | Start playback with optional URI and HTTP headers |
stopPlayer | Promise<string> | Stop playback | |
pausePlayer | Promise<string> | Pause playback | |
resumePlayer | Promise<string> | Resume playback | |
seekToPlayer | number milliseconds | Promise<string> | Seek to position in milliseconds |
setVolume | number value | Promise<string> | Set volume (0.0 - 1.0) |
setPlaybackSpeed | number speed | Promise<string> | Set playback speed (0.5 - 2.0) |
addRecordBackListener | Function callback | void | Add recording progress listener |
removeRecordBackListener | void | Remove recording progress listener | |
addPlayBackListener | Function callback | void | Add playback progress listener |
removePlayBackListener | void | Remove playback progress listener |
1import AudioRecorderPlayer, { 2 AudioEncoderAndroidType, 3 AudioSourceAndroidType, 4 AVEncoderAudioQualityIOSType, 5 AVEncodingOption, 6 RecordBackType, 7 PlayBackType, 8} from 'react-native-audio-recorder-player'; 9 10// AudioRecorderPlayer is a singleton instance, use directly 11 12// Recording 13const onStartRecord = async () => { 14 // Set up recording progress listener 15 AudioRecorderPlayer.addRecordBackListener((e: RecordBackType) => { 16 console.log('Recording progress:', e.currentPosition, e.currentMetering); 17 setRecordSecs(e.currentPosition); 18 setRecordTime(AudioRecorderPlayer.mmssss(Math.floor(e.currentPosition))); 19 }); 20 21 const result = await AudioRecorderPlayer.startRecorder(); 22 console.log('Recording started:', result); 23}; 24 25const onStopRecord = async () => { 26 const result = await AudioRecorderPlayer.stopRecorder(); 27 AudioRecorderPlayer.removeRecordBackListener(); 28 console.log('Recording stopped:', result); 29}; 30 31// Pause/Resume Recording 32const onPauseRecord = async () => { 33 await AudioRecorderPlayer.pauseRecorder(); 34 console.log('Recording paused'); 35}; 36 37const onResumeRecord = async () => { 38 await AudioRecorderPlayer.resumeRecorder(); 39 console.log('Recording resumed'); 40}; 41 42// Playback 43const onStartPlay = async () => { 44 // Set up playback progress listener 45 AudioRecorderPlayer.addPlayBackListener((e: PlayBackType) => { 46 console.log('Playback progress:', e.currentPosition, e.duration); 47 setCurrentPosition(e.currentPosition); 48 setTotalDuration(e.duration); 49 setPlayTime(AudioRecorderPlayer.mmssss(Math.floor(e.currentPosition))); 50 setDuration(AudioRecorderPlayer.mmssss(Math.floor(e.duration))); 51 }); 52 53 const result = await AudioRecorderPlayer.startPlayer(); 54 console.log('Playback started:', result); 55}; 56 57const onPausePlay = async () => { 58 await AudioRecorderPlayer.pausePlayer(); 59}; 60 61const onStopPlay = async () => { 62 AudioRecorderPlayer.stopPlayer(); 63 AudioRecorderPlayer.removePlayBackListener(); 64}; 65 66// Seeking 67const seekTo = async (milliseconds: number) => { 68 await AudioRecorderPlayer.seekToPlayer(milliseconds); 69}; 70 71// Volume control 72const setVolume = async (volume: number) => { 73 await AudioRecorderPlayer.setVolume(volume); // 0.0 - 1.0 74}; 75 76// Speed control 77const setSpeed = async (speed: number) => { 78 await AudioRecorderPlayer.setPlaybackSpeed(speed); // 0.5 - 2.0 79};
1const audioSet: AudioSet = { 2 // iOS Settings 3 AVSampleRateKeyIOS: 44100, 4 AVFormatIDKeyIOS: AVEncodingOption.aac, 5 AVEncoderAudioQualityKeyIOS: AVEncoderAudioQualityIOSType.high, 6 AVNumberOfChannelsKeyIOS: 2, 7 8 // Android Settings 9 AudioEncoderAndroid: AudioEncoderAndroidType.AAC, 10 AudioSourceAndroid: AudioSourceAndroidType.MIC, 11}; 12 13const meteringEnabled = true; // Enable audio metering 14 15const uri = await AudioRecorderPlayer.startRecorder( 16 undefined, // Use default path 17 audioSet, 18 meteringEnabled 19);
{cacheDir}/sound.mp4
.{cacheDir}/sound.m4a
.Tip: Store the file path returned by
startRecorder()
immediately for later use in playback or file management.
For better code organization, consider separating recording and playback into separate components:
Note: Starting from version 4.x, recording operations (start/stop) are processed in the background to prevent UI blocking. This means there's a slight delay between calling the method and the actual operation completing. We strongly recommend implementing loading states to provide better user experience.
1import React, { useState } from 'react'; 2import { View, Button, Text, ActivityIndicator } from 'react-native'; 3import AudioRecorderPlayer from 'react-native-audio-recorder-player'; 4 5export const AudioRecorder = ({ onRecordingComplete }) => { 6 const [isRecording, setIsRecording] = useState(false); 7 const [isLoading, setIsLoading] = useState(false); 8 const [recordTime, setRecordTime] = useState('00:00:00'); 9 10 const onStartRecord = async () => { 11 setIsLoading(true); 12 try { 13 const result = await AudioRecorderPlayer.startRecorder(); 14 AudioRecorderPlayer.addRecordBackListener((e) => { 15 setRecordTime(AudioRecorderPlayer.mmssss(Math.floor(e.currentPosition))); 16 }); 17 setIsRecording(true); 18 } catch (error) { 19 console.error('Failed to start recording:', error); 20 } finally { 21 setIsLoading(false); 22 } 23 }; 24 25 const onStopRecord = async () => { 26 setIsLoading(true); 27 try { 28 const result = await AudioRecorderPlayer.stopRecorder(); 29 AudioRecorderPlayer.removeRecordBackListener(); 30 setIsRecording(false); 31 onRecordingComplete?.(result); 32 } catch (error) { 33 console.error('Failed to stop recording:', error); 34 } finally { 35 setIsLoading(false); 36 } 37 }; 38 39 return ( 40 <View> 41 <Text>{recordTime}</Text> 42 <Button 43 title={isRecording ? 'Stop Recording' : 'Start Recording'} 44 onPress={isRecording ? onStopRecord : onStartRecord} 45 disabled={isLoading} 46 /> 47 {isLoading && <ActivityIndicator />} 48 </View> 49 ); 50};
1import React, { useState } from 'react'; 2import { View, Button, Text, ActivityIndicator } from 'react-native'; 3import AudioRecorderPlayer from 'react-native-audio-recorder-player'; 4 5export const AudioPlayer = ({ audioPath }) => { 6 const [isPlaying, setIsPlaying] = useState(false); 7 const [isLoading, setIsLoading] = useState(false); 8 const [playTime, setPlayTime] = useState('00:00:00'); 9 const [duration, setDuration] = useState('00:00:00'); 10 11 const onStartPlay = async () => { 12 setIsLoading(true); 13 try { 14 const msg = await AudioRecorderPlayer.startPlayer(audioPath); 15 AudioRecorderPlayer.addPlayBackListener((e) => { 16 setPlayTime(AudioRecorderPlayer.mmssss(Math.floor(e.currentPosition))); 17 setDuration(AudioRecorderPlayer.mmssss(Math.floor(e.duration))); 18 19 // Auto-stop when playback completes 20 if (e.duration > 0 && e.currentPosition >= e.duration - 100) { 21 setIsPlaying(false); 22 AudioRecorderPlayer.removePlayBackListener(); 23 } 24 }); 25 setIsPlaying(true); 26 } catch (error) { 27 console.error('Failed to start playback:', error); 28 } finally { 29 setIsLoading(false); 30 } 31 }; 32 33 const onStopPlay = async () => { 34 setIsLoading(true); 35 try { 36 await AudioRecorderPlayer.stopPlayer(); 37 AudioRecorderPlayer.removePlayBackListener(); 38 setIsPlaying(false); 39 setPlayTime('00:00:00'); 40 setDuration('00:00:00'); 41 } catch (error) { 42 console.error('Failed to stop playback:', error); 43 } finally { 44 setIsLoading(false); 45 } 46 }; 47 48 return ( 49 <View> 50 <Text>{playTime} / {duration}</Text> 51 <Button 52 title={isPlaying ? 'Stop' : 'Play'} 53 onPress={isPlaying ? onStopPlay : onStartPlay} 54 disabled={!audioPath || isLoading} 55 /> 56 {isLoading && <ActivityIndicator />} 57 </View> 58 ); 59};
Navigate to the example directory:
1cd example
Install dependencies:
1yarn install
Start the development server:
1yarn start
Run on your platform:
1# iOS 2yarn ios 3 4# Android 5yarn android
If you encounter this error when trying to record on iOS:
Ensure microphone permissions are properly configured in your Info.plist
:
1<key>NSMicrophoneUsageDescription</key> 2<string>Your app needs microphone access to record audio</string>
Clean and rebuild your iOS project:
1cd ios 2rm -rf build Pods 3pod install 4cd .. 5yarn ios
Make sure you're testing on a real device if using the simulator doesn't work. Some audio features require real hardware.
Verify the Nitro modules are properly linked by checking that the [NitroModules] 🔥 AudioRecorderPlayer is boosted by nitro!
message appears during pod install
.
pod install
after installing the package.minSdkVersion
is 24 or higher in android/build.gradle
.If you're experiencing build issues or runtime errors after updating the library:
1cd ios 2rm -rf ~/Library/Caches/CocoaPods 3rm -rf Pods 4rm -rf ~/Library/Developer/Xcode/DerivedData/* 5pod cache clean --all 6pod install 7cd ..
Then in Xcode:
1cd android 2./gradlew clean 3rm -rf ~/.gradle/caches/ 4cd ..
Then rebuild:
1yarn android 2# or 3npx react-native run-android
You can also try resetting Metro cache:
1npx react-native start --reset-cache
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library
No vulnerabilities found.
No security vulnerabilities found.