react-synth-plus
v1.0.8
Published
A high-performance, headless wavetable synthesizer for React built on Tone.js
Maintainers
Readme
🎹 React Synth Plus
React Synth Plus is a high-performance, headless wavetable synthesizer for React, built on top of the powerful Tone.js engine. Inspired by legendary synthesizers like Xfer Serum, it brings professional-grade audio synthesis to the browser with a modern, reactive developer experience.
✨ Key Features
- 🚀 Headless Architecture: Complete separation of audio logic and UI. Build your own synth interface using our custom React hooks.
- 🎨 Pre-built UI Components: Optional, modular components (Keyboard, Filters, FX) for instant dashboard creation.
- 🌊 Wavetable Engine: Smooth morphing between complex wavetable partials.
- 🎸 Built-in FX Rack: Professional distortion, reverb, and feedback delay out of the box.
- 🎹 Intelligent Keyboard Hook: Effortless QWERTY-to-MIDI mapping and polyphonic note management.
- 🧪 Rock Solid: Fully tested with Vitest and React Testing Library.
📦 Installation
npm install react-synth-plusNote: Ensure you have react, react-dom, and tone installed in your project.
1. Using Pre-built UI Components
The fastest way to get started. Import the components and the bundled CSS for a professional look.
import { useState } from 'react';
import { Keyboard, FilterControl, useAudioEngine } from 'react-synth-plus';
// Import the bundled styles (choose ONE of the following):
import 'react-synth-plus/dist/style.css';
// or if your bundler supports aliases:
// import 'react-synth-plus/style.css';
const MySynth = () => {
const { isStarted, init, setParam } = useAudioEngine();
const [filterState, setFilterState] = useState({ type: 'lowpass', cutoff: 2000 });
return (
<div className="p-10 bg-zinc-950 min-h-screen text-white">
{!isStarted ? (
<button className="bg-red-500 p-4 rounded" onClick={init}>Start Engine</button>
) : (
<div className="flex flex-col gap-4">
<FilterControl value={filterState} onChange={setParam} />
<Keyboard />
</div>
)}
</div>
);
};🏗️ UI Component Library
React Synth Plus ships with a set of modular, Tailwind-styled components. To use them, ensure you import react-synth-plus/style.css.
| Component | Description |
| :--- | :--- |
| <Keyboard /> | A full piano roll with mouse, touch, and QWERTY support. |
| <Visualizer /> | Real-time HTML5 Canvas oscilloscope. |
| <OscillatorControl /> | Controls for wavetable selection and morphing. |
| <FilterControl /> | Controls for filter mode and cutoff frequency. |
| <SubControl /> | Controls for the sub-oscillator. |
| <NoiseControl /> | Controls for the noise generator. |
| <LFOControl /> | Controls for LFO rate, depth, and routing. |
| <EnvelopeControl /> | Controls for the master ADSR envelope. |
| <FXControl /> | Controls for distortion, reverb, and delay. |
🚀 Headless Hooks (Advanced)
Build your own UI logic from scratch using the useAudioEngine hook.
import { useAudioEngine } from 'react-synth-plus';
const MySynth = () => {
const { isStarted, init, engine } = useAudioEngine();
return (
<div>
{!isStarted ? (
<button onClick={init}>Initialize Audio</button>
) : (
<button onMouseDown={() => engine.playNote('C4')} onMouseUp={() => engine.stopNote('C4')}>
Play C4
</button>
)}
</div>
);
};2. Controlling Parameters
Manipulate any part of the audio engine (Filters, Envelopes, FX) using the setParam(module, parameter, value) function.
import { useAudioEngine } from 'react-synth-plus';
const FilterControl = () => {
const { setParam } = useAudioEngine();
return (
<input
type="range" min="20" max="10000"
onChange={(e) => setParam('filter', 'cutoff', parseFloat(e.target.value))}
/>
);
};Available Parameters:
| Module | Parameter | Description |
| :--- | :--- | :--- |
| osc1 | wavetable, wtPos | Select table (basic, harmonic) and morph position (0-1). |
| filter | type, cutoff | Mode (lowpass, highpass, bandpass) and frequency (Hz). |
| sub | type, volume | Waveform and gain (0-1) for the sub oscillator. |
| noise | type, volume | Type (white, pink, brown) and gain (0-1). |
| lfo | type, rate, depth, target | LFO shape, speed (Hz), depth, and target (cutoff, pitch). |
| env | attack, release | ADSR timings (seconds) for the master amplitude envelope. |
| fx | dist, reverbMix, delayMix, delayTime, delayFeedback | Global distortion, reverb mix, and delay rack parameters. |
3. Building a Keyboard
Leverage useKeyboard for instant on-screen and QWERTY keyboard support.
import { useKeyboard } from 'react-synth-plus';
const MyKeyboard = () => {
const { pressedNotes, playNote, stopNote, keys } = useKeyboard();
return (
<div className="flex gap-1">
{keys.map(({ note, key, type }) => (
<div
key={note}
className={`p-4 border ${pressedNotes.has(note) ? 'bg-blue-500' : 'bg-white'}`}
onMouseDown={() => playNote(note)}
onMouseUp={() => stopNote(note)}
>
{key.toUpperCase()}
</div>
))}
</div>
);
};🛠️ Development & Examples
This repository includes a comprehensive Showcase Project that demonstrates all features in a single dashboard.
Run the Showcase
git clone https://github.com/hathibelagal-dev/react-synth-plus.git
cd react-synth-plus
npm install
npm run dev:showcaseBuilding the Library
npm run build:libRunning Tests
npm test📐 Architecture
[Your UI Components] <---> [Headless Hooks] <---> [Audio Engine (Tone.js)]
(Tailwind) (useAudioEngine) (PolySynth, FX)📜 License
Distributed under the GPL v3 License. See LICENSE for more information.
Made with ❤️ and a lot of oscillators.
