npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

audio-recording-sdk

v0.2.3

Published

React SDK for ambient audio recording with guaranteed uploads and offline support

Readme

audio-recording-sdk

React SDK for ambient audio recording with guaranteed uploads and offline support.

Records audio in chunks, persists every chunk to IndexedDB before uploading, and automatically resumes uploads when the network returns. Built for long sessions (3–5 hours).


Install

npm install audio-recording-sdk

Peer dependencies:

npm install react react-dom

Quick Start

import { useAudioRecorder, getAudios } from 'audio-recording-sdk';

export default function App() {
  const { startRecording, stopRecording, status, error } = useAudioRecorder();

  const handleGetAudios = async () => {
    const audios = await getAudios();
    console.log(audios); // list of all recordings for this device
  };

  return (
    <div>
      <button onClick={startRecording} disabled={status === 'recording'}>Start</button>
      <button onClick={stopRecording} disabled={status !== 'recording'}>Stop</button>
      <button onClick={handleGetAudios}>Get Audios</button>
      <p>Status: {status}</p>
      {error && <p>Error: {error.message}</p>}
    </div>
  );
}

API

useAudioRecorder(config?)

const { startRecording, stopRecording, status, error } = useAudioRecorder(config?);

| Option | Default | Description | |---|---|---| | headers | undefined | Added to every upload request — use for auth tokens | | chunkIntervalMs | 30000 | How often a new chunk is created (ms) | | maxRetries | 5 | Retry attempts per chunk with exponential backoff | | onChunkUploaded | undefined | Fires after each successful chunk upload | | onError | undefined | Fires on any error | | onStatusChange | undefined | Fires on every status change | | debug | false | Logs internal events to console |

startRecording()

Requests microphone permission and starts recording. Chunks are saved to IndexedDB and uploaded automatically.

stopRecording()

Stops recording and waits for all pending chunks to upload. Returns a RecordingSession.

interface RecordingSession {
  sessionId: string;
  startedAt: number;
  stoppedAt: number;
  totalChunks: number;
  uploadedChunks: number;
}

getAudios()

Fetches all recorded sessions for the current device. Returns an array of AudioSession.

const audios = await getAudios();

interface AudioSession {
  sessionId: string;
  createdAt: string;
  totalChunks: number;
  audioUrl: string; // direct URL to play the audio
}

Each device is identified by a unique ID generated on first use and stored in localStorage. All recordings made on the same device are returned.

status

type RecordingStatus =
  | 'idle'
  | 'requesting-permission'
  | 'recording'
  | 'paused'
  | 'uploading'
  | 'done'
  | 'error';

Sharing State Across Components

import { AudioRecorderProvider, useAudioRecorderContext } from 'audio-recording-sdk';

function App() {
  return (
    <AudioRecorderProvider>
      <RecordButton />
      <StatusDisplay />
    </AudioRecorderProvider>
  );
}

function RecordButton() {
  const { startRecording, stopRecording } = useAudioRecorderContext();
  // ...
}

Platform Support

| Platform | Screen lock | Background recording | |---|---|---| | Web browser | Best effort | Continues while tab is open | | Safari iOS (web only) | Stops | Not supported | | Capacitor iOS (native) | Continues | Full background support | | Capacitor Android (native) | Continues | Full background support |

The SDK auto-detects the platform at runtime and switches to the native adapter automatically. No code changes needed.


iOS Background Recording (Capacitor)

1. Install

npm install @capacitor/core @capacitor/ios audio-recording-sdk-plugin
npx cap add ios && npx cap sync ios

2. Configure Info.plist

<key>UIBackgroundModes</key>
<array>
  <string>audio</string>
</array>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required for audio recording.</string>

No code changes needed — SDK auto-detects Capacitor.


Android Background Recording (Capacitor)

1. Install

npm install @capacitor/core @capacitor/android audio-recording-sdk-plugin
npx cap add android && npx cap sync android

2. Register plugin in MainActivity.kt

import com.audiosdk.plugin.AudioRecorderPlugin

class MainActivity : BridgeActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        registerPlugin(AudioRecorderPlugin::class.java)
        super.onCreate(savedInstanceState)
    }
}

3. Add permissions to AndroidManifest.xml

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

No code changes needed — SDK auto-detects Capacitor. A persistent notification appears while recording (required by Android for background audio).


How Offline Works

Every chunk is saved to IndexedDB first, then uploaded. When the network drops:

  • Recording continues uninterrupted
  • Chunks accumulate in IndexedDB
  • Upload queue pauses automatically
  • When network returns, all pending chunks upload in order

Chunks survive page refreshes and app restarts. On the next startRecording() call, any unuploaded chunks from previous sessions are recovered and re-queued automatically.


Error Handling

const { error } = useAudioRecorder({
  onError: (err) => console.error(err.code, err.message),
});

type SDKErrorCode =
  | 'PERMISSION_DENIED'
  | 'RECORDER_ERROR'
  | 'STORAGE_ERROR'
  | 'UPLOAD_ERROR'
  | 'NETWORK_ERROR';

Known Limitations

  • Safari iOS (web only): Recording pauses when the screen locks. Use Capacitor for uninterrupted recording.
  • Android Chrome (web only): Recording pauses when the screen locks. Use Capacitor for uninterrupted recording.
  • Screen lock (any browser): Pressing the power button suspends browser JS on all platforms — use Capacitor native for guaranteed background recording.
  • Private browsing: IndexedDB is unavailable. SDK falls back to in-memory storage — chunks are lost if tab closes before upload completes.

License

MIT