Skip to main content

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 UIs
  • ADSRView — Interactive ADSR envelope editor with drag handles
  • AudioWaveform — Audio waveform display component
  • SessionClipSlot — Clip slot for session/performance view
  • CodeEditor — CodeMirror-based text editor (used by ScriptFX and BirdFilePanel)

Molecules (molecules/)

Composed components combining multiple atoms:
  • LevelMeter — per-track audio level visualization
  • PluginSlots — instrument/FX/strip slot management
  • MuteSoloButtons, PanControl, VolumeFader — mixer controls
  • StereoMeters — spectrum, stereo width, phase correlation meters
  • RecordStrip — MIDI/audio recording controls per track
  • PluginShell / PluginHeader / PluginBody / PluginSection — shared layout components for stock plugin UIs
  • EditorPanelShell — container shell for custom editor panels

Organisms (organisms/)

Larger self-contained UI blocks:
  • MixerChannel / MasterChannel — full channel strips
  • TrackHeader / TrackLane — arrangement view rows
  • TimelineRuler — bar/beat ruler
  • GenerateInlinePopup — Option+click-drag inline AI generation overlay
  • LoadingScreen — first-load overlay; ExportStatusIndicator — inline progress widget mounted in StatusBar

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 from mixer.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/vite plugin)
  • 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. The window.__SONGBIRD__ global is injected by the Tauri bridge and provides the backend event system. All commands go through send() from @/sync/api or invoke() from @/sync/transports/promiseHandler.