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

@waveform-playlist/browser

v15.4.0

Published

Browser bundle for waveform-playlist with React

Readme

@waveform-playlist/browser

React components, hooks, and context providers for building a multitrack Web Audio editor and player — canvas waveform rendering, clip-based editing, and playback controls on top of Tone.js or a native HTMLAudioElement.

Features

  • Multitrack editor<Waveform /> renders canvas waveforms, per-track controls (mute/solo/volume/pan), a time ruler, and a playhead for any number of tracks
  • Clip-based editing — drag-to-move, boundary trimming with collision detection, splitting at the playhead, snap-to-grid (beats/bars or timescale), undo/redo
  • Split context providersWaveformPlaylistProvider (multitrack, Tone.js-backed) and MediaElementPlaylistProvider (single-track, <audio>-backed with pitch-preserving playback rate)
  • Four focused context hooksusePlaybackAnimation, usePlaylistState, usePlaylistControls, usePlaylistData isolate 60fps playhead updates from low-frequency state so unrelated components don't re-render on every animation frame
  • Audio effects — 20 Tone.js effects (reverb, delay, modulation, filter, distortion, dynamics, spatial) with runtime parameter control, master and per-track chains, plus WAM 2.0 plugin hosting
  • Recording — pairs with @waveform-playlist/recording for mic input, overdubbing, and live waveform preview; punch-in takes replace overlapped content, and setRecordingActive(active, armedTrackId) suppresses the end-of-timeline auto-stop and transiently mutes the recorded-over track for the session
  • Annotations & spectrogram — optional integration contexts for @waveform-playlist/annotations and @waveform-playlist/spectrogram
  • WAV export — render the full mix (including effects) offline to a downloadable WAV file
  • MediaElement player mode — a lightweight single-track player with pitch-preserving speed control, for podcast/audiobook-style use cases that don't need multitrack mixing

Installation

npm install @waveform-playlist/browser tone @dnd-kit/react

@waveform-playlist/browser requires these peer dependencies:

| Package | Purpose | |---------|---------| | react / react-dom | ^18.0.0 or ^19.0.0 | | styled-components | ^6.0.0 — CSS-in-JS styling | | tone | ^15.0.0 — Web Audio engine (optional if you supply your own PlayoutAdapter) | | @dnd-kit/react | ^0.3.0 — drag-and-drop (includes @dnd-kit/dom and @dnd-kit/abstract) | | @waveform-playlist/playout | Tone.js playout engine (optional peer, dynamically imported by default) | | @waveform-playlist/media-element-playout | engine for MediaElementPlaylistProvider (optional peer) | | @waveform-playlist/annotations / @waveform-playlist/recording / @dawcore/wam | optional, install only if you use those features |

Engine-free core: the package's main entry has no static dependency on tone or @waveform-playlist/playout — a MediaElementPlaylistProvider-only consumer, or one supplying a custom createAdapter, never resolves either. Tone-coupled exports (useAudioTracks, useDynamicTracks, effects hooks, useExportWav, useOutputMeter, useMasterAnalyser) live at the @waveform-playlist/browser/tone subpath:

import { useAudioTracks, useDynamicEffects, useExportWav } from '@waveform-playlist/browser/tone';

Quick Start

import {
  WaveformPlaylistProvider,
  Waveform,
  PlayButton,
  PauseButton,
  StopButton,
} from '@waveform-playlist/browser';
import { useAudioTracks } from '@waveform-playlist/browser/tone';

function MyPlaylist() {
  const { tracks, loading, error } = useAudioTracks([
    { src: '/audio/vocals.mp3', name: 'Vocals' },
    { src: '/audio/guitar.mp3', name: 'Guitar' },
  ]);

  if (loading) return <div>Loading audio...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <WaveformPlaylistProvider
      tracks={tracks}
      samplesPerPixel={1024}
      waveHeight={128}
      timescale
      controls={{ show: true, width: 200 }}
    >
      <div style={{ display: 'flex', gap: '0.5rem', marginBottom: '1rem' }}>
        <PlayButton />
        <PauseButton />
        <StopButton />
      </div>
      <Waveform />
    </WaveformPlaylistProvider>
  );
}

Prefer a lightweight single-track player instead? Use MediaElementPlaylistProvider with @waveform-playlist/media-element-playout — no Tone.js, no AudioBuffer decoding, and pitch-preserving playback rate out of the box.

Context Hooks

WaveformPlaylistProvider splits its context into four hooks so components only re-render for the data they actually read:

| Hook | Exposes | |------|---------| | usePlaybackAnimation | isPlaying, currentTime, animation refs, getPlaybackTime(), registerFrameCallback() for 60fps-driven UI (playhead, progress bars) | | usePlaylistState | Low-frequency state — selection, loop region, annotations, selectedTrackId, canUndo/canRedo | | usePlaylistControls | Actions — play, pause, stop, seekTo, track mute/solo/volume/pan, zoom, undo/redo, setRecordingActive (recording-session suppression + armed-track mute) | | usePlaylistData | Derived/config data — tracks, duration, sampleRate, peaksDataArray, trackStates, isReady |

usePlaylistDataOptional is the same as usePlaylistData but returns null outside a provider (for components that render both inside and outside one). MediaElementPlaylistProvider has the equivalent useMediaElementAnimation, useMediaElementState, useMediaElementControls, useMediaElementData.

Examples & Documentation

License

MIT