A multi-track audio editor and player built with React, Tone.js, and the Web Audio API. Features canvas-based waveform visualization, drag-and-drop clip editing, and professional audio effects.
- Multi-track editing - Multiple clips per track with drag-to-move and trim
- Waveform visualization - Canvas-based rendering with zoom controls
- 20+ audio effects - Reverb, delay, filters, distortion, and more via Tone.js
- Recording - AudioWorklet-based recording with live waveform preview
- Export - WAV export with effects, individual tracks or full mix
- Annotations - Time-synced text annotations with keyboard navigation
- Theming - Full theme customization with dark/light mode support
- MIDI playback - MIDI file parsing with piano roll visualization and SoundFont sample playback
- TypeScript - Full type definitions included
npm install @waveform-playlist/browser tone @dnd-kit/reactNote:
toneand@dnd-kit/reactare peer dependencies and must be installed separately.@dnd-kit/domand@dnd-kit/abstractare transitive dependencies of@dnd-kit/react.
import { WaveformPlaylistProvider, Waveform, PlayButton, PauseButton, StopButton } from '@waveform-playlist/browser';
import { createTrack, createClipFromSeconds } from '@waveform-playlist/core';
function App() {
const [tracks, setTracks] = useState([]);
// Load audio and create tracks
useEffect(() => {
async function loadAudio() {
const response = await fetch('/audio/song.mp3');
const arrayBuffer = await response.arrayBuffer();
const audioContext = new AudioContext();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
const track = createTrack({
name: 'My Track',
clips: [createClipFromSeconds({ audioBuffer, startTime: 0 })],
});
setTracks([track]);
}
loadAudio();
}, []);
return (
<WaveformPlaylistProvider tracks={tracks}>
<div>
<PlayButton />
<PauseButton />
<StopButton />
</div>
<Waveform />
</WaveformPlaylistProvider>
);
}- Live Examples - Interactive demos
- Getting Started - Installation and basic usage
- Guides - In-depth tutorials
- API Reference - Component and hook documentation
| Example | Description |
|---|---|
| Stem Tracks | Multi-track playback with mute/solo/volume controls |
| Effects | 20 Tone.js effects with real-time parameter control |
| Recording | Live recording with VU meter and waveform preview |
| Multi-Clip | Drag-and-drop clip editing with trim handles |
| Annotations | Time-synced text with keyboard navigation |
| Waveform Data | Pre-computed peaks for fast loading |
| MIDI | MIDI file playback with piano roll and SoundFont samples |
| Beats & Bars | Tempo-synced timescale with beats and bars ruler |
| Fades | Fade in/out with configurable curves |
| Stereo | Stereo waveform rendering and pan controls |
| Spectrogram | FFT-based spectrogram visualization |
| Media Element | HTMLMediaElement playout with playback rate |
| Styling | Bar width, gaps, gradients, and theme colors |
| Flexible API | Custom playheads, timestamps, and full UI customization |
| Package | Description |
|---|---|
@waveform-playlist/browser |
Main React components, hooks, and context |
@waveform-playlist/core |
Types, utilities, and clip/track creation |
@waveform-playlist/engine |
Framework-agnostic timeline engine with pure operations |
@waveform-playlist/ui-components |
Styled UI components (buttons, sliders, etc.) |
@waveform-playlist/playout |
Tone.js audio engine |
@waveform-playlist/webaudio-peaks |
Peak extraction from AudioBuffer or sample arrays |
@waveform-playlist/loaders |
Audio loaders |
Optional packages:
| Package | Description |
|---|---|
@waveform-playlist/midi |
MIDI file parsing, piano roll visualization, and SoundFont playback |
@waveform-playlist/annotations |
Time-synced text annotations with drag editing |
@waveform-playlist/recording |
AudioWorklet recording with live waveform preview (requires setup) |
@waveform-playlist/worklets |
Shared AudioWorklet processors for metering and recording (auto-installed with recording) |
@waveform-playlist/spectrogram |
Spectrogram visualization with FFT worker |
@waveform-playlist/media-element-playout |
HTMLMediaElement-based playout with pitch-preserving playback rate |
// Load audio files into tracks
const { tracks, loading, error } = useAudioTracks([
{ src: '/audio/vocals.mp3', name: 'Vocals' },
{ src: '/audio/drums.mp3', name: 'Drums' },
]);
// Playback controls
const { play, pause, stop, seekTo } = usePlaylistControls();
// Playback animation (60fps updates)
const { currentTime, isPlaying } = usePlaybackAnimation();
// Zoom controls
const { zoomIn, zoomOut, samplesPerPixel } = useZoomControls();
// Master effects chain
const { masterEffects, toggleBypass, updateParameter } = useDynamicEffects();
// WAV export
const { exportWav, isExporting, progress } = useExportWav();
// Recording
const { startRecording, stopRecording, isRecording } = useIntegratedRecording();@dawcore/components provides framework-agnostic Web Components for multi-track audio editing — no React required. Built with Lit, using @dawcore/transport for native Web Audio playback (no Tone.js dependency).
npm install @dawcore/components<script type="module">
import '@dawcore/components';
</script>
<daw-editor id="editor" clip-headers interactive-clips timescale file-drop>
<daw-track name="Vocals">
<daw-clip src="/audio/vocals.mp3" start="0" duration="10"></daw-clip>
</daw-track>
<daw-keyboard-shortcuts playback splitting undo></daw-keyboard-shortcuts>
</daw-editor>
<daw-transport for="editor">
<daw-play-button></daw-play-button>
<daw-pause-button></daw-pause-button>
<daw-stop-button></daw-stop-button>
<daw-record-button></daw-record-button>
</daw-transport>Features:
- Declarative
<daw-track>and<daw-clip>elements with auto-loading - Clip move, trim, and split with collision detection
- Undo/redo with transaction-based grouping
- Keyboard shortcuts (Space=play/pause, S=split, Cmd/Ctrl+Z=undo)
- File drop for adding tracks
- Recording with overdub and latency compensation
- Metronome with mixed meters and tempo changes
- Tempo automation — linear ramps and Möbius-Ease curves with exact integration
- Pre-computed peaks for fast initial render
- Native Web Audio — no Tone.js, full
sampleRateandlatencyHintcontrol
Packages:
| Package | Description |
|---|---|
@dawcore/components |
Lit Web Components for multi-track editing |
@dawcore/transport |
Native Web Audio transport — scheduling, looping, tempo automation, time signatures, metronome |
Run the examples locally:
cd packages/dawcore && pnpm dev:pageThen open http://localhost:5173/dev/ — example pages:
index.html— Basic playback with timescale and file dropmulticlip.html— Multi-clip editing with move, trim, and splitrecord.html— Recording with overdubmetronome.html— Metronome with mixed meters, tempo presets, and looping sequencesautomation.html— Tempo automation with step, linear, and curve presets
Requires Web Audio API support: Chrome, Firefox, Safari, Edge (modern versions).
# Install dependencies
pnpm install
# Start dev server
pnpm website
# Run tests
pnpm test
# Build all packages
pnpm buildVisit http://localhost:3000/waveform-playlist to see the examples.
Currently writing: Mastering Tone.js
Originally created for the Airtime project at Sourcefabric.
