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

@julianfrank/micmanager

v2025.4.210

Published

The MicManager is a TypeScript library (v2025.4.21) that provides a comprehensive interface for managing microphone input, audio recording, and waveform visualization in web applications. It offers a customizable UI component with microphone selection, re

Readme

MicManager Documentation

The MicManager is a TypeScript library (v2025.4.21) that provides a comprehensive interface for managing microphone input, audio recording, and waveform visualization in web applications. It offers a customizable UI component with microphone selection, recording controls, and real-time audio visualization.

Table of Contents

Features

  • 🎤 Microphone device selection and management
  • 🎚️ Audio recording controls with start/stop functionality
  • 📊 Real-time waveform visualization with configurable parameters
  • 🎯 Custom stream target support for advanced audio processing
  • 🎨 Fully customizable UI elements with theming support
  • 🔄 Automatic microphone list updates with caching
  • ⚡ Efficient event handling and automatic resource cleanup
  • 🔒 Built-in error handling and type safety with TypeScript
  • 📱 Responsive design with mobile device support

Installation

npm install @julianfrank/micmanager

Basic Usage

First, import the MicManager class:

import { MicManager } from '@julianfrank/micmanager';

Then create a new instance and initialize the UI:

// Create a new MicManager instance with default settings
const micManager = new MicManager({
    rootElement: document.getElementById('mic-container'),
    startButtonText: '🎙️ Start',
    stopButtonText: '⏹️ Stop',
    onStartRecording: (stream) => {
        console.log('Recording started', stream);
    },
    onStopRecording: () => {
        console.log('Recording stopped');
    }
});

// Initialize the UI with waveform visualization
micManager.createMicUI({
    waveform: {
        enabled: true,
        width: 300,
        height: 150,
        backgroundColor: '#000000',
        waveformColor: '#00ff00',
        resolution: 32,
        refreshRate: 30
    }
});

// Optional: Customize the appearance
micManager.setStyle({
    backgroundColor: '#f0f0f0',
    waveformColor: '#ff0000',
    waveformBackgroundColor: '#333333',
    buttonBackgroundColor: '#ffffff',
    buttonShadowColor: 'rgba(0,0,0,0.3)',
    micListBackgroundColor: '#ffffff',
    micListBorderColor: '#cccccc'
});

TypeScript Support

MicManager comes with full TypeScript support. The package includes type definitions for all classes, interfaces, and methods.

Using Types in Your Project

import { MicManager, MicUIParameters, StreamTarget, WaveformConfig } from '@julianfrank/micmanager';

// Create a strongly-typed configuration
const config: MicUIParameters = {
    rootElement: document.getElementById('mic-container') as HTMLElement,
    waveform: {
        enabled: true,
        width: 300,
        height: 150
    }
};

// Create a custom stream target with proper typing
class CustomAudioProcessor implements StreamTarget {
    setStream(stream: MediaStream | null): void {
        // Implementation
    }
    
    start(): void {
        // Implementation
    }
    
    stop(): void {
        // Implementation
    }
}

const micManager = new MicManager(config);
micManager.setStreamTarget(new CustomAudioProcessor());

Available Types

The package exports the following types:

  • MicManager - The main class
  • Microphone - Interface for microphone device information
  • StreamTarget - Interface for custom audio stream handlers
  • WaveformConfig - Interface for waveform visualization configuration
  • MicUIParameters - Interface for UI configuration parameters
  • MicUIElements - Interface for created UI elements
  • MicManagerError, StreamError, DeviceError - Error classes

Architecture

classDiagram
    class MicManager {
        -stream: MediaStream | null
        -rootElement: HTMLElement
        -elements: MicUIElements | null
        -streamTarget: StreamTarget | null
        -useDefaultAudioElement: boolean
        -eventListeners: Map
        -micListCache: Microphone[] | null
        -micListCacheTimestamp: number
        -audioContext: AudioContext | null
        -analyser: AnalyserNode | null
        -waveformConfig: WaveformConfig
        -animationFrameId: number | null
        +constructor(params: MicUIParameters)
        +createMicUI(params: MicUIParameters): MicUIElements
        +setStreamTarget(target: StreamTarget): void
        +clearStreamTarget(): void
        +getMicrophoneList(): Promise<Microphone[]>
        +toggleMicSettings(enabled: boolean): void
        +toggleWaveform(enabled: boolean): void
        +setStyle(styles: object): void
        +dispose(): void
        -addEventListenerWithCleanup(element, type, listener): void
        -removeEventListeners(element): void
        -updateMicList(micList, microphones): void
        -handleMicChange(): Promise<void>
        -startRecording(deviceId): Promise<void>
        -stopRecording(): void
        -updateWaveformPosition(): void
        -setupWaveform(stream): void
        -drawWaveform(): void
        -stopWaveform(): void
    }

    class StreamTarget {
        <<interface>>
        +setStream(stream: MediaStream | null): void
        +start?(): void
        +stop?(): void
        +onStreamStart?(): void
        +onStreamStop?(): void
        +onStreamError?(error: Error): void
    }

    class MicUIElements {
        <<interface>>
        +micWidget: HTMLDivElement
        +micSettingsContainer: HTMLDivElement
        +settingsButton: HTMLDivElement
        +micList: HTMLSelectElement
        +startButton: HTMLDivElement
        +stopButton: HTMLDivElement
        +audioElement: HTMLAudioElement
        +waveformCanvas?: HTMLCanvasElement
        +waveformContainer?: HTMLDivElement
    }

    class WaveformConfig {
        <<interface>>
        +enabled?: boolean
        +width?: number
        +height?: number
        +resolution?: number
        +refreshRate?: number
        +backgroundColor?: string
        +waveformColor?: string
    }

    class MicManagerError {
        +name: string
        +constructor(message: string)
    }

    class StreamError {
        +name: string
        +constructor(message: string)
    }

    class DeviceError {
        +name: string
        +constructor(message: string)
    }

    MicManager --> StreamTarget : uses
    MicManager --> MicUIElements : creates
    MicManager --> WaveformConfig : configures
    StreamError --|> MicManagerError : extends
    DeviceError --|> MicManagerError : extends

Interfaces

MicUIParameters

interface MicUIParameters {
    rootElement?: HTMLElement;              // Container element for the UI
    streamTarget?: StreamTarget;            // Custom audio stream handler
    onMicListChange?: (mics: Microphone[]) => void;  // Microphone list update callback
    onStartRecording?: (stream: MediaStream) => void; // Recording start callback
    onStopRecording?: () => void;          // Recording stop callback
    onAudioElementError?: (error: Error) => void;
    startButtonText?: string;               // Custom start button text
    stopButtonText?: string;                // Custom stop button text
    waveform?: WaveformConfig;             // Waveform visualization config
    showMicSettings?: boolean;             // Whether to show mic settings by default
}

StreamTarget

interface StreamTarget {
    // Required method
    setStream(stream: MediaStream | null): void;
    
    // Optional methods
    start?(): void;
    stop?(): void;
    
    // Optional event handlers
    onStreamStart?(): void;
    onStreamStop?(): void;
    onStreamError?(error: Error): void;
}

WaveformConfig

interface WaveformConfig {
    enabled?: boolean;           // Enable/disable waveform visualization
    width?: number;             // Canvas width in pixels
    height?: number;            // Canvas height in pixels
    resolution?: number;        // FFT size / 2
    refreshRate?: number;       // Updates per second
    backgroundColor?: string;   // Canvas background color
    waveformColor?: string;    // Waveform line color
}

Microphone

interface Microphone {
    deviceId: string;   // Unique device identifier
    label: string;      // Human-readable device name
}

API Reference

Constructor

constructor(params: MicUIParameters)

Creates a new MicManager instance. Only one instance can exist at a time.

Methods

createMicUI

createMicUI(params: MicUIParameters): MicUIElements

Creates and returns the UI elements for microphone management.

setStreamTarget

setStreamTarget(target: StreamTarget): void

Sets a custom stream target for handling the audio stream.

clearStreamTarget

clearStreamTarget(): void

Removes the custom stream target and reverts to using the default audio element.

getMicrophoneList

async getMicrophoneList(): Promise<Microphone[]>

Returns a list of available microphone devices.

dispose

dispose(): void

Cleans up resources and removes UI elements.

toggleMicSettings

toggleMicSettings(enabled: boolean): void

Enables or disables the microphone settings interface.

toggleWaveform

toggleWaveform(enabled: boolean): void

Enables or disables the waveform visualization. If disabled while recording, the waveform will stop; if enabled while recording, the waveform will start.

setStyle

setStyle(styles: {
    backgroundColor?: string;
    waveformColor?: string;
    waveformBackgroundColor?: string;
    buttonBackgroundColor?: string;
    buttonShadowColor?: string;
    micListBackgroundColor?: string;
    micListBorderColor?: string;
}): void

Sets custom styles for various UI components. All parameters are optional:

  • backgroundColor: Background color of the main widget
  • waveformColor: Color of the waveform line
  • waveformBackgroundColor: Background color of the waveform canvas
  • buttonBackgroundColor: Background color of all buttons
  • buttonShadowColor: Shadow color for all buttons
  • micListBackgroundColor: Background color of the microphone selection dropdown
  • micListBorderColor: Border color of the microphone selection dropdown

Examples

Basic Recording with Waveform

const micManager = new MicManager({
    rootElement: document.getElementById('mic-container')
});

const ui = micManager.createMicUI({
    startButtonText: '🎙️ Start',
    stopButtonText: '⏹️ Stop',
    waveform: {
        enabled: true,
        width: 300,
        height: 150,
        resolution: 32,
        refreshRate: 30,
        backgroundColor: '#000000',
        waveformColor: '#00ff00'
    },
    onStartRecording: (stream) => {
        console.log('Recording started');
    },
    onStopRecording: () => {
        console.log('Recording stopped');
    }
});

Custom UI Configuration

const micManager = new MicManager({
    rootElement: document.getElementById('mic-container')
});

const ui = micManager.createMicUI({
    startButtonText: '🎙️ Start',
    stopButtonText: '⏹️ Stop',
    showMicSettings: true,
    waveform: {
        enabled: true,
        width: 300,
        height: 150
    }
});

// Customize the appearance
micManager.setStyle({
    backgroundColor: '#f0f0f0',
    waveformColor: '#ff0000',
    waveformBackgroundColor: '#333333',
    buttonBackgroundColor: '#ffffff',
    buttonShadowColor: 'rgba(0,0,0,0.3)',
    micListBackgroundColor: '#ffffff',
    micListBorderColor: '#cccccc'
});

// Toggle UI components
micManager.toggleMicSettings(true);  // Show mic settings
micManager.toggleWaveform(false);    // Hide waveform

// Later, when recording starts
micManager.toggleWaveform(true);     // Show waveform during recording

Custom Stream Target

class AudioProcessor implements StreamTarget {
    private audioContext: AudioContext;
    private processor: ScriptProcessorNode;

    constructor() {
        this.audioContext = new AudioContext();
    }

    setStream(stream: MediaStream | null): void {
        if (stream) {
            const source = this.audioContext.createMediaStreamSource(stream);
            source.connect(this.processor);
        }
    }

    start(): void {
        console.log('Processing started');
    }

    stop(): void {
        console.log('Processing stopped');
    }

    onStreamError(error: Error): void {
        console.error('Stream error:', error);
    }
}

const micManager = new MicManager({
    rootElement: document.getElementById('mic-container'),
    streamTarget: new AudioProcessor()
});

micManager.createMicUI({
    waveform: { enabled: true }
});

Error Handling

The MicManager provides custom error types for better error handling:

// Base error type
class MicManagerError extends Error {
    name = "MicManagerError";
}

// Stream-related errors
class StreamError extends MicManagerError {
    name = "StreamError";
}

// Device-related errors
class DeviceError extends MicManagerError {
    name = "DeviceError";
}

// Error handling example
try {
    await micManager.startRecording();
} catch (error) {
    if (error instanceof StreamError) {
        console.error('Stream error:', error.message);
    } else if (error instanceof DeviceError) {
        console.error('Device error:', error.message);
    } else {
        console.error('Unknown error:', error);
    }
}

Development

Prerequisites

  • Node.js (Latest LTS version recommended)
  • npm or yarn

Setup

  1. Clone the repository
  2. Install dependencies:
npm install

Available Scripts

  • npm run dev - Start development server with hot reload
  • npm run build - Build for production
  • npm run preview - Preview production build

Dependencies

  • TypeScript 5.8.3
  • Vite 6.3.2
  • @vitejs/plugin-basic-ssl 2.0.0
  • vite-plugin-css-injected-by-js 3.5.2

Best Practices

  1. Singleton Usage: Only one MicManager instance should exist at a time.
  2. Resource Cleanup: Always call dispose() when the MicManager is no longer needed.
  3. Error Handling: Implement proper error handling using the provided error types.
  4. Stream Target: Use custom stream targets for advanced audio processing.
  5. Waveform Configuration: Adjust waveform settings based on performance requirements.
  6. Mobile Support: Test on various devices and screen sizes.
  7. Memory Management: Properly dispose of instances to prevent memory leaks.

Browser Support

MicManager requires browsers that support:

  • MediaDevices API
  • getUserMedia
  • Web Audio API
  • Canvas API

Supported Browsers:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

This project is licensed under the MIT License.