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

bionic-audio

v1.1.1

Published

Professional Windows WASAPI audio recorder library for Node.js and Bun - record microphone and system audio with advanced features

Readme

bionic-audio

Professional Windows WASAPI audio recorder library for Node.js and Bun. Record microphone, system loopback, or both simultaneously with support for multiple audio formats and advanced quality settings.

Status: Production Ready | Platform: Windows 10/11 | Architecture: x64, ia32

Features

  • 🎤 Microphone Recording: Capture input from your microphone
  • 🔊 Loopback Recording: Capture system audio (what's playing on speakers)
  • 🎙️ Dual Recording: Record both microphone and loopback simultaneously
  • 📊 Multiple Formats: 16-bit PCM, 24-bit PCM, or 32-bit float WAV files
  • ⏱️ Duration Control: Record for a specific duration or indefinitely
  • 🎛️ Gain Control: Amplify or reduce signal strength
  • 📡 Stream to stdout: Raw PCM streaming for real-time processing
  • 🧵 Threaded Capture: Dedicated thread for capture operations
  • 🔌 Easy Integration: EventEmitter-based interface with promise support

Installation

npm install bionic-audio

Or globally for CLI access:

npm install -g bionic-audio

Requirements

  • Windows 10/11
  • Node.js 14+ or Bun
  • recorder.exe binary (included in package, or build from source)

Quick Start

Basic Recording

import { recordToFile } from 'bionic-audio';

// Simple file recording - 5 seconds of system audio
await recordToFile('./output.wav', { duration: 5 });

EventEmitter Interface

import { AudioRecorder } from 'bionic-audio';

const recorder = new AudioRecorder({
  output: './recording.wav',
  duration: 10,
  preserve32: true  // 32-bit float format
});

recorder.on('started', () => console.log('🎤 Recording started'));
recorder.on('data', (bytes) => console.log(`📝 Wrote ${bytes} bytes`));
recorder.on('error', (err) => console.error('❌ Error:', err));
recorder.on('complete', (result) => {
  console.log('✅ Recording complete:', result);
});

recorder.start();

// Stop manually (or wait for duration to finish)
setTimeout(() => recorder.stop(), 5000);

Promise-Based Interface

import { AudioRecorder } from 'bionic-audio';

const recorder = new AudioRecorder();

try {
  const result = await recorder.record({
    duration: 5,
    output: './output.wav'
  });
  
  console.log(`✅ Recording finished with exit code ${result.code}`);
} catch (error) {
  console.error('❌ Recording failed:', error);
}

Convenience Functions

import { 
  recordToFile, 
  recordMicrophone, 
  recordLoopback, 
  recordBoth 
} from 'bionic-audio';

// Record system audio (loopback) to file
await recordToFile('./output.wav', { duration: 10 });

// Record microphone only
await recordMicrophone('./mic.wav', { duration: 10 });

// Record system audio only
await recordLoopback('./system.wav', { duration: 10 });

// Record both simultaneously (two separate files)
await recordBoth('./combined.wav', { duration: 10 });

Streaming to stdout

import { AudioRecorder } from 'bionic-audio';
import { createWriteStream } from 'fs';

const recorder = new AudioRecorder();
const output = createWriteStream('./stream.wav');

recorder.pipe(output);
recorder.start({ duration: 5, pcmOnly: true });

API Reference

new AudioRecorder(options?)

Creates a new audio recorder instance.

Options:

  • output?: string - Output file path (required for file recording)
  • duration?: number - Recording duration in seconds (0 = infinite, default: 0)
  • gain?: number - Signal gain/amplitude multiplier (default: 1.0)
  • preserve24?: boolean - Keep 24-bit native format (default: false)
  • preserve32?: boolean - Keep 32-bit float format (default: false)
  • pcmOnly?: boolean - Output raw PCM without WAV header (default: false)
  • loopback?: boolean - Record system audio instead of microphone (default: false)
  • microphone?: boolean - Record microphone (default: true)
  • both?: boolean - Record both simultaneously (default: false)
  • threaded?: boolean - Use dedicated capture thread (default: false)

Methods

start(options?): void

Starts recording with optional runtime options.

stop(): boolean

Stops the recording process. Returns true if stopped, false if not running.

isRecording(): boolean

Check if currently recording.

record(options?): Promise<RecorderResult>

Promise-based recording. Blocks until recording completes or errors.

const result = await recorder.record({ duration: 5 });
// result: { code: number, signal: string | null, stderr: string }

pipe(destination: NodeJS.WritableStream): void

Pipe raw audio data to a writable stream (e.g., for real-time processing).

getProcess(): ChildProcess | null

Access the underlying child process directly.

Events

  • started - Recording has started
  • data(bytes: number) - Data written (number of bytes)
  • stderr(data: string) - Stderr output from recorder
  • exit(code: number, signal: string | null) - Process exited
  • complete(result: RecorderResult) - Recording completed successfully
  • error(error: Error) - Error occurred

Convenience Functions

recordToFile(path: string, options?: RecorderOptions): Promise<RecorderResult>

Quick file recording.

recordMicrophone(path: string, options?: RecorderOptions): Promise<RecorderResult>

Record microphone only.

recordLoopback(path: string, options?: RecorderOptions): Promise<RecorderResult>

Record system audio only.

recordBoth(path: string, options?: RecorderOptions): Promise<RecorderResult>

Record both microphone and loopback simultaneously.

Configuration

Audio Quality

  • 16-bit PCM (default): Balanced quality and file size, ~1.5 MB/min for stereo at 48kHz
  • 24-bit PCM (preserve24: true): Higher quality, ~2.3 MB/min
  • 32-bit float (preserve32: true): Highest quality, lossless internal format, ~3 MB/min

Gain Control

// Amplify by 2x
recorder.start({ gain: 2.0 });

// Reduce by half
recorder.start({ gain: 0.5 });

Gain is applied before clipping to prevent distortion.

Electron Integration

import { AudioRecorder } from 'bionic-audio';
import { ipcMain } from 'electron';

let recorder: AudioRecorder | null = null;

ipcMain.handle('start-recording', async (event, options) => {
  recorder = new AudioRecorder(options);
  
  recorder.on('error', (err) => {
    event.sender.send('recording-error', err.message);
  });
  
  recorder.start();
  return { ok: true };
});

ipcMain.handle('stop-recording', async () => {
  recorder?.stop();
  return { ok: true };
});

Building from Source

# Install dependencies
npm install

# Compile TypeScript
npm run build

# Build C++ recorder binary (requires MinGW or MSVC)
gcc -o recorder.exe main.c -lole32 -std=c99

Troubleshooting

"recorder.exe not found"

Ensure the binary is in PATH or in one of these locations:

  • ./recorder.exe
  • ./bin/recorder.exe
  • ../recorder.exe
  • ./dist/recorder.exe

Distorted/Noisy Audio

Try enabling gain control with values < 1.0:

recorder.start({ gain: 0.8 });

File Won't Play

Ensure you're using a compatible audio player. 32-bit float WAV support varies. Try 16-bit output:

recorder.start({ preserve32: false });

License

MIT