> ## Documentation Index
> Fetch the complete documentation index at: https://songbird.studiocollective.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Songbird React UI (`react_ui/`)

# Songbird React UI (`react_ui/`)

The React frontend provides the full DAW interface for Songbird. It runs inside a Tauri v2 WebView (not a regular browser) and communicates with the Rust backend through the **sync engine** — a single typed dispatch (`songbird_sync::dispatch`) that all UI ↔ backend traffic flows through. The same UI also runs against a headless Rust WebSocket server for browser-based e2e tests and the WASM build for the web app.

## Tech Stack

* **React 19** — UI framework
* **Vite** — Build tool with `@vitejs/plugin-react-swc`
* **TypeScript** — Type safety
* **Tailwind CSS v4** — Utility-first styling (via `@tailwindcss/vite`)
* **Zustand** — Lightweight state management with persistence
* **Radix UI** — Accessible primitive components
* **class-variance-authority** — Component variant styling
* **@tonaljs** — Music theory (chords, notes, scales)
* **@codemirror** — Code editor (ScriptFX, BirdFilePanel)

## Project Structure

```
react_ui/
├── src/
│   ├── App.tsx           — Root component, panel layout, loading state
│   ├── main.tsx          — Entry point, React root mount
│   ├── sentry.ts         — Sentry error tracking initialization
│   ├── components/       — UI components (atomic design: atoms → panels)
│   ├── data/             — State management (Zustand stores, meters, feature flags)
│   ├── sync/             — Sync engine client (api.ts, channels/, transports/, wiring.ts)
│   ├── hooks/            — Custom React hooks (useGhostNotes, useCollabCursorTracking, etc.)
│   ├── lib/              — Non-React utilities (theme, AI agents, GL renderer, native bridges)
│   ├── services/         — External service clients (collabSocket.ts, collabMixerSync.ts)
│   └── assets/           — Static assets
├── index.html            — HTML entry point
├── vite.config.ts        — Vite configuration
├── vitest.config.ts      — Vitest test configuration
├── tsconfig.app.json     — TypeScript config
└── package.json          — Dependencies
```

## Build & Development

The preferred workflow is `./utils/build-rs` from the repo root, which boots the Vite dev server and the Tauri shell together with HMR. The raw npm scripts still work:

```bash theme={null}
cd react_ui
npm install
npm run dev      # Vite dev server (standalone browser development)
npm run build    # Production build → dist/ (embedded into the Tauri app)
```

> **Important:** In production, the React app runs inside Tauri v2's WebView (or, for `songbird-headless` / `songbird-wasm`, against a Rust WebSocket server). All backend calls go through the sync engine — `send()` / `sendRT()` from `@/sync/api`. Direct Tauri `invoke()` is reserved for OS dialogs only (see Hard Rule #1 in `CLAUDE.md`).

## Backend communication

A single typed pipeline carries every UI ↔ backend message:

* **Commands** — `send('channel.action', payload)` from `@/sync/api`. High-frequency knob/slider drags use `sendRT(...)` to skip guards and echo suppression.
* **Events** — incoming events are subscribed in `@/sync/wiring.ts` and the per-channel `events.ts` modules, then mirrored into Zustand stores.
* **Transports** — Tauri IPC in desktop, WebSocket in headless/web, in-process dispatch in WASM. All three share the same `dispatch` API.
* **Persistence** — settings that must survive a reload live in a sync-engine channel with its own `PersistenceStrategy`. Never `localStorage` or Zustand's `persist` middleware.

## Key Conventions

* **Atomic Design**: Components organized as atoms → molecules → organisms → panels
* **Tailwind-only styling**: No CSS modules or styled-components. Use `cn()` from `@/lib/utils` for conditional classes
* **Zustand for state**: Never use React Context or prop drilling for shared state
* **Direct DOM for meters**: High-frequency visuals (level meters, playheads) use `subscribeRtBuffer()` + direct DOM manipulation, bypassing React's render cycle
* **Path aliases**: `@/` maps to `src/` (configured in `tsconfig.app.json`)

## Testing

The React UI uses **Vitest** for unit testing. Test files live alongside the code they test (e.g., `data/slices/mixer.test.ts`).

```bash theme={null}
cd react_ui
npx vitest run        # Run all tests once
npx vitest            # Watch mode
```

Current test coverage includes:

* Zustand store slices (`chat.test.ts`, `generate.test.ts`, `mixer.test.ts`, `transport.test.ts`)
* Store integration tests (`store.test.ts`)
* Utility tests (`sliderDrag.test.ts`)

## Recent Additions

* **Inline AI Generation** — Option+click-drag on arrangement tracks to generate audio (Lyria) or MIDI directly at a position. Uses `GenerateInlinePopup` organism and `inlineGenerate` slice.
* **Collaboration** — `CollabCursors` component renders Figma-style multiplayer cursors. `CollabPanel` shows connected users and invite codes. `collabMixerSync.ts` provides optimistic mixer state sync.
* **Stock Plugin UIs** — Premium-quality plugin editors in `components/plugins/` using shared `PluginShell`/`PluginBody`/`PluginSection` layout components and `RotaryKnob`/`ADSRView` atoms.
* **ScriptFX Editor** — `ScriptFXEditorPanel` provides a CodeMirror-based editor for writing DSP scripts (JavaScript or Faust/WASM).
* **Sheet Music & Guitar Tabs** — `SheetMusicView` and `GuitarTabView` panels for rendered notation and tablature.
* **Specialized AI Agents** — Composer, mix engineer, sound designer, and audio creator agents in `lib/ai/agents/` with intent-based routing.
* **Custom Editor Framework** — `CustomEditorPanel` and `EditorPanelShell` in panels, with `customEditors` slice for managing which plugin UIs to render.

## Error Tracking

Sentry integration is initialised in `sentry.ts` for the WebView layer. The Rust side runs its own `sentry` crate integration (activated by the analytics channel — see `rust/crates/data/songbird-analytics/`); both feed into the same project.
