Modular Web Audio Components for React
Build synthesizers, effects processors, drum machines, and generative music apps with composable React components
Documentation โข Playground โข Quick Start โข Examples
MOD brings the philosophy of hardware modular synthesizers to React. Instead of wrestling with the low-level Web Audio API or being constrained by opinionated libraries, MOD gives you composable building blocks that snap together just like modules in a modular synth rack.
// A complete synthesizer in 10 lines
<AudioProvider>
<Sequencer output={seq} gateOutput={gate} bpm={120} />
<ADSR gate={gate} output={env} attack={0.01} decay={0.3} sustain={0.5} release={0.5} />
<ToneGenerator output={tone} cv={seq} frequency={220} />
<Filter input={tone} output={filtered} type="lowpass" frequency={800} />
<VCA input={filtered} output={vca} cv={env} gain={0} />
<Delay input={vca} output={delayed} time={0.375} feedback={0.4} />
<Reverb input={delayed} output={final} />
<Monitor input={final} />
</AudioProvider>That's a complete step sequencer โ envelope โ oscillator โ filter โ VCA โ delay โ reverb signal chain. No imperative code, no manual node management, just React components.
MOD mirrors hardware modular synthesizers:
- Components are modules (oscillators, filters, envelopes, effects)
- Refs are patch cables (connect outputs to inputs)
- CV props are modulation (LFOs and envelopes control parameters)
- Signal flow is visual (your JSX mirrors your audio graph)
Choose the right approach for each use case:
1. Render Props - Build custom UIs
<ToneGenerator output={ref}>
{({ frequency, setFrequency }) => (
<Slider value={frequency} onChange={setFrequency} />
)}
</ToneGenerator>2. Controlled Props - External state management
const [freq, setFreq] = useState(440);
<ToneGenerator output={ref} frequency={freq} onFrequencyChange={setFreq} />3. Imperative Refs - Programmatic control
const ref = useRef<ToneGeneratorHandle>(null);
// Later: ref.current?.setFrequency(880);Hardware-inspired control voltage routing:
<LFO output={lfo} frequency={3} />
<Filter input={audio} output={out} cv={lfo} cvAmount={5000} />
// LFO sweeps filter cutoff ยฑ5000HzConnect any CV source (LFO, ADSR, Sequencer) to any parameter for dynamic, audio-rate modulation.
Complete UI control - build with anything:
- Native HTML inputs
- ModUI (included) - Pre-built audio controls (Knob, Slider, XYPad)
- Your component library (Material-UI, Chakra, etc.)
- Mobile, desktop, web, anywhere React runs
- TypeScript-first - Comprehensive types for everything
- Zero dependencies - Core library has no external deps
- React-native - Built FOR React, not adapted to it
- Automatic cleanup - No memory leaks or manual lifecycle
- Hot module reload - Changes reflect instantly during development
npm install @mode-7/modimport { AudioProvider, ToneGenerator, Monitor, useModStream } from '@mode-7/mod';
function Synth() {
const tone = useModStream();
return (
<AudioProvider>
<ToneGenerator output={tone} frequency={440} />
<Monitor input={tone} />
</AudioProvider>
);
}import { LFO, ToneGenerator, Monitor, useModStream } from '@mode-7/mod';
function ModulatedSynth() {
const lfo = useModStream();
const tone = useModStream();
return (
<AudioProvider>
<LFO output={lfo} frequency={5} />
<ToneGenerator output={tone} frequency={440} cv={lfo} cvAmount={100} />
<Monitor input={tone} />
</AudioProvider>
);
}import { ToneGenerator, Monitor, Slider } from '@mode-7/mod';
function InteractiveSynth() {
const tone = useModStream();
return (
<AudioProvider>
<ToneGenerator output={tone}>
{({ frequency, setFrequency }) => (
<Slider
label="Frequency"
value={frequency}
onChange={setFrequency}
min={20}
max={2000}
/>
)}
</ToneGenerator>
<Monitor input={tone} />
</AudioProvider>
);
}Generate or capture audio
- ToneGenerator - Oscillator (sine, square, sawtooth, triangle)
- NoiseGenerator - White and pink noise
- Microphone - Live audio input
- MP3Deck - Audio file playback
- StreamingAudioDeck - Stream from URLs
Control voltage for modulation
- LFO - Low-frequency oscillator (0.01-20Hz)
- ADSR - Attack-Decay-Sustain-Release envelope
- Sequencer - Step sequencer with CV and gate outputs
- Clock - Tempo sync and gate triggers
Transform audio signals
Filters & EQ:
- Filter - Multi-mode filter (8 types) with CV modulation
- EQ - 3-band parametric EQ
- AutoWah - Envelope-following filter
Time-Based:
- Delay - Echo with feedback
- Reverb - Convolution reverb
Modulation:
- Chorus - Thick, wide chorus
- Flanger - Sweeping comb filter
- Phaser - Phase-shifting modulation
- Tremolo - Amplitude modulation
- RingModulator - Metallic ring mod
Dynamics:
- Compressor - Dynamic range compression
- Limiter - Peak limiting
- Gate - Noise gate
- VCA - Voltage controlled amplifier
Distortion:
- Distortion - Waveshaping distortion
- BitCrusher - Lo-fi degradation
Spatial:
- Panner - Stereo panning with CV
Combine signals
- Mixer - 4-channel mixer
- CrossFade - Crossfade between two inputs
- Monitor - Audio output with device selection
Real-time analysis
- Oscilloscope - Waveform display
- SpectrumAnalyzer - Frequency spectrum
- LevelMeter - Audio level metering
Pre-built audio controls
Controls:
- Slider - Range slider with +/- buttons
- Knob - Rotary control (270ยฐ rotation)
- XYPad - 2D control surface
- Button - Customizable button
- Select - Dropdown selector
- TextInput - Text input field
- FilePicker - File selection
- ProgressBar - Progress/scrub bar
Visualizations:
- OscilloscopeCanvas - Waveform renderer
- SpectrumAnalyzerCanvas - Spectrum renderer
- LevelMeterCanvas - Level meter renderer
function DrumMachine() {
const clock = useModStream();
const kickSeq = useModStream();
const kickGate = useModStream();
const kickEnv = useModStream();
const kick = useModStream();
return (
<AudioProvider>
{/* Tempo control */}
<Clock output={clock} bpm={120} />
{/* Kick drum */}
<Sequencer output={kickSeq} gateOutput={kickGate} steps={[1,0,0,0, 1,0,0,0]} />
<ToneGenerator output={kick} frequency={60} cv={kickSeq} />
<ADSR gate={kickGate} output={kickEnv} attack={0.001} decay={0.3} sustain={0} />
<VCA input={kick} output={kick} cv={kickEnv} />
<Monitor input={kick} />
</AudioProvider>
);
}function EffectsChain() {
const input = useModStream();
const filtered = useModStream();
const compressed = useModStream();
const delayed = useModStream();
const output = useModStream();
return (
<AudioProvider>
<Microphone output={input} />
<Filter input={input} output={filtered} type="lowpass" frequency={1000} />
<Compressor input={filtered} output={compressed} threshold={-20} ratio={4} />
<Delay input={compressed} output={delayed} time={0.25} feedback={0.3} />
<Reverb input={delayed} output={output} />
<Monitor input={output} />
</AudioProvider>
);
}function AmbientGenerator() {
const lfo1 = useModStream();
const lfo2 = useModStream();
const osc1 = useModStream();
const osc2 = useModStream();
const mixed = useModStream();
const filtered = useModStream();
const output = useModStream();
return (
<AudioProvider>
{/* Slow-moving LFOs */}
<LFO output={lfo1} frequency={0.1} />
<LFO output={lfo2} frequency={0.07} />
{/* Two oscillators with LFO modulation */}
<ToneGenerator output={osc1} frequency={220} cv={lfo1} cvAmount={50} />
<ToneGenerator output={osc2} frequency={330} cv={lfo2} cvAmount={75} />
{/* Mix and process */}
<Mixer inputs={[osc1, osc2]} output={mixed} levels={[0.5, 0.5]} />
<Filter input={mixed} output={filtered} type="lowpass" cv={lfo1} cvAmount={2000} />
<Reverb input={filtered} output={output} decay={5} />
<Monitor input={output} />
</AudioProvider>
);
}Perfect for building:
- ๐น Synthesizers and virtual instruments
- ๐ฅ Drum machines and samplers
- ๐ธ Guitar pedal emulators and effect chains
- ๐ผ Generative music and algorithmic composition
- ๐ Educational tools for teaching audio/synthesis
- ๐ฎ Game audio engines
- ๐จ Audio-reactive visualizations
- ๐ง Browser-based DAWs and production tools
Web Audio API:
const audioContext = new AudioContext();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
const filter = audioContext.createBiquadFilter();
oscillator.connect(gainNode);
gainNode.connect(filter);
filter.connect(audioContext.destination);
oscillator.start();
// Manual cleanup, state sync, lifecycle management...MOD:
<AudioProvider>
<ToneGenerator output={tone} />
<Filter input={tone} output={filtered} />
<Monitor input={filtered} />
</AudioProvider>MOD abstracts the complexity while maintaining full control.
Tone.js is excellent for music-focused apps with built-in instruments and a transport system.
MOD excels at:
- React-native integration (built FOR React)
- Complete UI control (headless components)
- Modular synthesis paradigm (CV routing)
- Three flexible usage patterns
- Granular control when needed
Choose Tone.js for music theory utilities and built-in instruments. Choose MOD for React apps, custom UIs, and modular synthesis.
MOD follows a signal-flow architecture:
- Sources generate audio (oscillators, noise, microphone, files)
- CV Generators produce control signals (LFO, envelopes, sequencers)
- Processors transform audio (filters, effects, dynamics)
- Mixers combine multiple signals
- Output sends to speakers/headphones
- Visualizations observe signals (non-destructive)
Connect modules using refs:
const stream = useModStream(); // Creates a connection point
<Source output={stream} /> // Outputs to stream
<Processor input={stream} /> // Reads from streamModulate parameters using CV:
<LFO output={lfo} />
<Filter input={audio} cv={lfo} cvAmount={5000} />Full documentation: mode7labs.github.io/mod
- Getting Started
- Architecture
- CV Modulation
- API Reference
- Playground - Interactive examples
- Chrome 35+
- Firefox 25+
- Safari 14.1+
- Edge 79+
Any browser with Web Audio API support.
We welcome contributions! See CONTRIBUTING.md for guidelines.
Check out CONTRIBUTORS.md for planned features and future work.
MIT License - see LICENSE
Built with โค๏ธ for the Web Audio community.
Inspired by hardware modular synthesizers and the creative possibilities of React.
Ready to build something amazing?
