Songbird React UI (react_ui/src/)
The React frontend provides the full DAW interface for Songbird, running inside a Tauri WebView. Built with Vite, React 19, Tailwind CSS v4, and Zustand for state management.
Architecture Overview
Component Structure (Atomic Design)
Atoms (atoms/)
Reusable primitives built on Radix UI. Styled with Tailwind + class-variance-authority:
button,input,select,slider,knob,switch,tabs,toast,tooltip, etc.RotaryKnob— Rotary parameter knob with arc visualization, used across all stock plugin UIsADSRView— Interactive ADSR envelope editor with drag handlesAudioWaveform— Audio waveform display componentSessionClipSlot— Clip slot for session/performance viewCodeEditor— CodeMirror-based text editor (used by ScriptFX and BirdFilePanel)
Molecules (molecules/)
Composed components combining multiple atoms:
LevelMeter— per-track audio level visualizationPluginSlots— instrument/FX/strip slot managementMuteSoloButtons,PanControl,VolumeFader— mixer controlsStereoMeters— spectrum, stereo width, phase correlation metersRecordStrip— MIDI/audio recording controls per trackPluginShell/PluginHeader/PluginBody/PluginSection— shared layout components for stock plugin UIsEditorPanelShell— container shell for custom editor panels
Organisms (organisms/)
Larger self-contained UI blocks:
MixerChannel/MasterChannel— full channel stripsTrackHeader/TrackLane— arrangement view rowsTimelineRuler— bar/beat rulerGenerateInlinePopup— Option+click-drag inline AI generation overlayLoadingScreen— first-load overlay;ExportStatusIndicator— inline progress widget mounted inStatusBar
State Management
Zustand Stores (data/)
Stores are organized to mirror Rust’s StateManager slices (10 domain slices).
Types live in their canonical domain module and are re-exported from mixer.ts
for backward compatibility.
Domain Type Modules
Types are defined in their canonical domain module and re-exported frommixer.ts for backward compatibility:
Domain Selector Hooks (data/hooks/useTrackDomain.ts)
Per-track domain hooks provide render isolation via useShallow:
Event-Only Hydration
Zustand stores are pure UI caches — no persistence middleware. Rust pushes initial state via events on startup (settings.react_ready), and all runtime updates flow through the same event path:
Key Event Channels
Key Libraries
- React 19 — UI framework
- Tailwind CSS v4 — Utility-first styling (via
@tailwindcss/viteplugin) - Zustand — Lightweight state management
- Radix UI — Accessible primitive components
- class-variance-authority — Component variant styling
- @tonaljs — Music theory calculations (chord, note, tonal)
Development
Note: In production, the React app runs inside the Tauri WebView — not a browser. Thewindow.__SONGBIRD__global is injected by the Tauri bridge and provides the backend event system. All commands go throughsend()from@/sync/apiorinvoke()from@/sync/transports/promiseHandler.