Introduction

A modern Web Audio framework for building interactive music apps.

Tone.js wraps the low-level Web Audio API with musician-friendly constructs (Synth, Sampler, Transport), giving you DAW-like power in the browser

// play a middle-C for an 8th-note
import * as Tone from "tone";
const synth = new Tone.Synth().toDestination();
await Tone.start();          // user-gesture gate
synth.triggerAttackRelease("C4","8n");

Installation & Setup

Grab via NPM, ESM import, or UNPKG script tag.

  1. NPM / Yarn

    npm install tone            # latest stable
    npm install tone@next       # bleeding edge
  2. ESM import

    import * as Tone from "tone";
  3. UNPKG CDN

    <script src="https://unpkg.com/tone"></script>

πŸ‘‰ Remember to call Tone.start() after a user event before making sound

Core Building Blocks

Synths, Players, the Signal chain, and the global Transport.

3.1 Transport & Timed Events

The Tone.getTransport() clock synchronises every scheduled callback. Start, stop, loop, change tempo, and quantise events reliably


// quarter-note loop on C2
const synth = new Tone.FMSynth().toDestination();
const loop = new Tone.Loop((time)=>{
    synth.triggerAttackRelease("C2","8n",time);
},"4n").start(0);
Tone.getTransport().bpm.value = 120;
Tone.getTransport().start();

3.2 Mono & Poly Synths

Create basses, leads or poly pads instantly with built-ins like Synth, FMSynth, and PolySynth.

3.3 Samples & Players

Load single shots via Player, or multi-sample instruments with Samplerβ€”complete with pitch-shifting

3.4 Effects & Routing

Insert or parallel-route any number of effects (Delay, Reverb, Distortion). Patch nodes exactly like physical cables.

// serial effect chain
const player = new Tone.Player("loop.mp3").start();
const delay  = new Tone.FeedbackDelay("8n",0.4).toDestination();
player.connect(delay);

Advanced Audio-Graph Topics

Latency, custom nodes, and AudioWorklets.

  1. Latency Hints β€” pass { latencyHint:"playback" } to minimise glitching on mobile.

  2. AudioWorklet Support β€” v14.7 introduced direct AudioWorkletNode constructors for DSP in a worker

  3. Custom Param Interpolations β€” drive any Signal with ramps, curves, or external LFOs.

MIDI & External Input

Play your synths with real hardware.

// Basic Web-MIDI β†’ Tone synth
if (navigator.requestMIDIAccess){
  const synth = new Tone.PolySynth(Tone.Synth).toDestination();
  navigator.requestMIDIAccess().then(access=>{
    access.inputs.forEach(inp=>{
      inp.onmidimessage = e=>{
        const [cmd,note,vel] = e.data;
        if (cmd===144 && vel>0)     synth.triggerAttack(Tone.Frequency(note,"midi"));
        if (cmd===128 || vel===0)   synth.triggerRelease(Tone.Frequency(note,"midi"));
      }
    });
  });
}

Recording & Export

Render in real-time or offline to WAV.

Use Tone.Recorder for live capture, or Tone.Offline to render faster-than-real-time for glitch-free bounces.

// live record
const rec = new Tone.Recorder();
synth.connect(rec);
await rec.start();
await Tone.start();
synth.triggerAttackRelease("C4","2n");
const wav = await rec.stop();
download(wav,"take-1.wav");

Performance  Tips

Keep CPU low and timing tight.

  1. Batch sample loads with Tone.loaded().

  2. Dispose unused nodes via .dispose() to free memory.

  3. Query Tone.context.baseLatency to adapt buffer sizes per device.

What’s New in v14.7.x (2025)

Biggest API shifts and fresh features.

FeatureNotes
Typescript MigrationEntire codebase now ships with .d.ts for intellisense
AudioWorklet SupportReal-time DSP off the main thread
Destination renameMaster ➜ Destination for clarity
Param ImprovementsSignals are simpler (SyncedSignal) and more powerful.

Further Reading & Community

Docs, examples, and inspiring tutorials.

  1. Official Docs & API Reference.

  2. GitHub Releases.

  3. Interactive Examples.

Example UIs (Gallery)

Swipe horizontally to explore Tone-powered apps.

Step Sequencer UI PolySynth Pad Drum Machine