tonejs
Web Audio framework for creating interactive music in browsers. Use when building audio applications, synthesizers, musical instruments, effects processors, audio visualizations, DAWs, step sequencers, or any browser-based sound generation. Handles synthesis, scheduling, sample playback, effects, and audio routing.
What this skill does
# Tone.js Skill
Build interactive music applications in the browser using the Web Audio API through Tone.js's high-level abstractions.
## When to Use This Skill
Use Tone.js when:
- Creating synthesizers, samplers, or musical instruments
- Building step sequencers, drum machines, or DAWs
- Adding sound effects or music to games
- Implementing audio visualizations synchronized to sound
- Processing audio in real-time with effects
- Scheduling musical events with precise timing
- Working with musical concepts (notes, tempo, measures)
## Core Concepts
### 1. Context and Initialization
The AudioContext must be started from a user interaction (browser requirement):
```javascript
import * as Tone from "tone";
// ALWAYS call Tone.start() from user interaction
document.querySelector("button").addEventListener("click", async () => {
await Tone.start();
console.log("Audio context ready");
// Now safe to play audio
});
```
### 2. Audio Graph and Routing
All audio nodes connect in a graph leading to `Tone.Destination` (the speakers):
```javascript
// Basic connection
const synth = new Tone.Synth().toDestination();
// Chain through effects
const synth = new Tone.Synth();
const filter = new Tone.Filter(400, "lowpass");
const delay = new Tone.FeedbackDelay(0.125, 0.5);
synth.chain(filter, delay, Tone.Destination);
// Parallel routing (split signal)
const reverb = new Tone.Reverb().toDestination();
const delay = new Tone.Delay(0.2).toDestination();
synth.connect(reverb);
synth.connect(delay);
```
### 3. Time and Scheduling
Tone.js abstracts time in musical notation:
- `"4n"` = quarter note
- `"8n"` = eighth note
- `"2m"` = two measures
- `"8t"` = eighth note triplet
- Numbers = seconds
**CRITICAL**: Always use the `time` parameter passed to callbacks:
```javascript
// CORRECT - sample-accurate timing
const loop = new Tone.Loop((time) => {
synth.triggerAttackRelease("C4", "8n", time);
}, "4n");
// WRONG - JavaScript timing is imprecise
const loop = new Tone.Loop(() => {
synth.triggerAttackRelease("C4", "8n"); // Will drift
}, "4n");
```
### 4. Transport System
The global timekeeper for synchronized events:
```javascript
// Schedule events on the Transport
const loop = new Tone.Loop((time) => {
synth.triggerAttackRelease("C4", "8n", time);
}, "4n").start(0);
// Control the Transport
Tone.Transport.start();
Tone.Transport.stop();
Tone.Transport.pause();
Tone.Transport.bpm.value = 120; // Set tempo
```
## Step-by-Step Instructions
### Task 1: Create a Basic Synthesizer
1. Import Tone.js
2. Create a synth and connect to output
3. Wait for user interaction to start audio
4. Play notes using `triggerAttackRelease`
```javascript
import * as Tone from "tone";
const synth = new Tone.Synth().toDestination();
button.addEventListener("click", async () => {
await Tone.start();
// Play C4 for an eighth note
synth.triggerAttackRelease("C4", "8n");
});
```
### Task 2: Create a Polyphonic Instrument
1. Use `PolySynth` to wrap a monophonic synth
2. Pass multiple notes to play chords
3. Release specific notes when needed
```javascript
const polySynth = new Tone.PolySynth(Tone.Synth).toDestination();
// Play a chord
polySynth.triggerAttack(["C4", "E4", "G4"]);
// Release specific notes
polySynth.triggerRelease(["E4"], "+1");
```
### Task 3: Load and Play Audio Files
1. Create a `Player` or `Sampler`
2. Wait for `Tone.loaded()` promise
3. Start playback
```javascript
const player = new Tone.Player("https://example.com/audio.mp3").toDestination();
await Tone.loaded();
player.start();
// For multi-sample instruments
const sampler = new Tone.Sampler({
urls: {
C4: "C4.mp3",
"D#4": "Ds4.mp3",
"F#4": "Fs4.mp3",
},
baseUrl: "https://example.com/samples/",
}).toDestination();
await Tone.loaded();
sampler.triggerAttackRelease(["C4", "E4"], 1);
```
### Task 4: Create a Looping Pattern
1. Use `Tone.Loop` or `Tone.Sequence` for patterns
2. Pass the time parameter to instrument triggers
3. Start the loop and the Transport
```javascript
const synth = new Tone.Synth().toDestination();
const loop = new Tone.Loop((time) => {
synth.triggerAttackRelease("C4", "8n", time);
}, "4n").start(0);
await Tone.start();
Tone.Transport.start();
```
### Task 5: Add Effects Processing
1. Create effect instances
2. Connect in desired order (serial or parallel)
3. Adjust wet/dry mix if needed
```javascript
const synth = new Tone.Synth();
const distortion = new Tone.Distortion(0.4);
const reverb = new Tone.Reverb({
decay: 2.5,
wet: 0.5, // 50% effect, 50% dry
});
synth.chain(distortion, reverb, Tone.Destination);
```
### Task 6: Automate Parameters
1. Access parameter via property (e.g., `frequency`, `volume`)
2. Use methods like `rampTo`, `linearRampTo`, `exponentialRampTo`
3. Schedule changes with time parameter
```javascript
const osc = new Tone.Oscillator(440, "sine").toDestination();
osc.start();
// Ramp frequency to 880 Hz over 2 seconds
osc.frequency.rampTo(880, 2);
// Set value at specific time
osc.frequency.setValueAtTime(440, "+4");
// Exponential ramp (better for frequency)
osc.frequency.exponentialRampTo(220, 1, "+4");
```
### Task 7: Synchronize Visuals with Audio
1. Use `Tone.Draw.schedule()` for visual updates
2. Schedule in the same callback as audio events
3. Visual updates happen just before audio plays
```javascript
const loop = new Tone.Loop((time) => {
synth.triggerAttackRelease("C4", "8n", time);
// Schedule visual update
Tone.Draw.schedule(() => {
element.classList.add("active");
}, time);
}, "4n");
```
## Common Patterns
### Pattern: Step Sequencer
```javascript
const synth = new Tone.Synth().toDestination();
const notes = ["C4", "D4", "E4", "G4"];
const seq = new Tone.Sequence(
(time, note) => {
synth.triggerAttackRelease(note, "8n", time);
},
notes,
"8n"
).start(0);
Tone.Transport.start();
```
### Pattern: Probabilistic Playback
```javascript
const loop = new Tone.Loop((time) => {
if (Math.random() > 0.5) {
synth.triggerAttackRelease("C4", "8n", time);
}
}, "8n");
```
### Pattern: Dynamic Effect Parameters
```javascript
const filter = new Tone.Filter(1000, "lowpass").toDestination();
const lfo = new Tone.LFO(4, 200, 2000); // 4Hz, 200-2000Hz range
lfo.connect(filter.frequency);
lfo.start();
```
## Sound Design Principles
### Core Insights
**Auditory processing is 10x faster than visual** (~25ms vs ~250ms). Sound provides immediate feedback that makes interactions feel responsive. A button that clicks *feels* faster than one that doesn't, even with identical visual feedback.
**Sound communicates emotion instantly.** A single tone conveys success, error, or tension better than visual choreography. When audio and visuals tell the same story together, the experience is stronger than either alone.
**Less is more.** Most interactions should be silent. Reserve sound for moments that matter: confirmations for major actions, errors that can't be overlooked, state transitions, and notifications. Always pair sound with visuals for accessibility - sound enhances, never replaces. Study games for reference - they've perfected informative, emotional, non-intrusive audio feedback.
### Design Philosophy
Good sound design transforms user experience across all platforms - web apps, mobile apps, desktop applications, and games. These principles apply universally whether creating notification sounds, UI feedback, or musical interactions.
Sound uses a universal language understood by everyone. When designing audio:
**Ask foundational questions:**
- What is the essence of what this app/feature is about?
- What emotion do you want to evoke?
- How does it match the app's visual aesthetics?
- How would users understand this interaction without looking at the screen?
**Consider context:**
- Where will users hear this? (Pocket, desk, busy street, quiet room)
- What will they be doing? (Working, commuting, gaming)
- How often will they hear it? (Once per day vs hundreds of times)
### Notification Sound DesRelated in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.