# Vocero React frontend React 19, TypeScript, Tailwind CSS 4, and Vite 8 client for the existing `s2s-client` FastAPI backend. This is a client-side application with React-owned rendering and state, including the realtime WebSocket and audio integration. ## Run during development Use Node.js 22.18 or later on the 22.x line, or Node.js 24+. Install dependencies with npm; the lockfile is committed. 1. Start the existing backend using `./start_ui.sh` from your configured S2S checkout, or reuse an already-running instance. It normally listens on port `8420` and continues serving the original static UI there. Its Python environment, `.env`, speech service, and upstream services must be configured as before. 2. In a second terminal, start this frontend: ```sh cd frontend-s2s npm ci npm run dev ``` 3. Open `http://127.0.0.1:5173`. Add `?debug=true` to access settings, tools, and custom RAG context. Existing `phoneNumber` and `episode_id` query parameters are supported. Vite serves React and Tailwind with hot updates. It proxies `/api`, `/v1/realtime` (including WebSockets), OAuth, and backend documentation routes to FastAPI. The browser uses one origin on port `5173`, so there is no separate API origin or development CORS setup. The proxy preserves the incoming Host header because FastAPI uses it to construct the speech WebSocket URL. For a different backend, copy `.env.example` to `.env.local` and set `S2S_BACKEND_URL`. This is a **Vite server** setting. Runtime UI flags, voices, reasoning mode, prompts, and the speech URL still come from FastAPI's `/api/config`. A backend explicitly configured with `SPEECH_TO_SPEECH_URL` continues to return that direct speech endpoint. The Vite configuration reads only this project's environment files. Do not copy the repository's backend secrets into this directory or into `VITE_*` variables, which are exposed to browser code. For access through a development reverse proxy, set the exact hostname in `S2S_DEV_ALLOWED_HOSTS`. Use `npm run dev -- --host 0.0.0.0` only when Vite must listen beyond localhost. The browser needs HTTPS for microphone access outside localhost, and that proxy must forward WebSocket upgrades for both speech and Vite HMR. Wiring the staging entrypoint and launcher is a separate step: **this port does not change `start_ui.sh`.** Component and CSS changes use Fast Refresh. Editing the session controller or audio modules can require restarting a conversation or a page reload. Teardown closes microphone tracks, worklets, sockets, queue tickets, timers, and pending requests on session stop or page exit. ## Checks and commands The scripts and code style follow `frontend-admin` conventions, with Vite and React plugins replacing Next.js-specific tooling. Executable configuration files use TypeScript; TypeScript's own project settings use JSON. | Command | Purpose | | -------------------- | ----------------------------------------------------------- | | `npm run dev` | Vite development server on port 5173, with a fixed port | | `npm run check` | Formatting, strict typed ESLint, type checking, and tests | | `npm run lint:fix` | Apply ESLint fixes | | `npm run format` | Format source and sort Tailwind classes | | `npm run typecheck` | Check application, tests, audio worklets, and configuration | | `npm test` | Run Vitest and React Testing Library regression tests | | `npm run test:watch` | Watch tests while editing | | `npm run build` | Typecheck and compile the app and worklets into `dist/` | | `npm run preview` | Inspect the compiled output locally | No build step is needed before `npm run dev`. `dist/` is generated and ignored by Git. Build output is available for later serving integration; this change does not mount it in FastAPI or change the staging launch process. Tests cover session initialization, response sequencing, cumulative transcripts, interruptions, queue cancellation, microphone-permission cancellation, tool results, external reasoning and `LOG_ONLY`, late-response cleanup, the idle timeout, settings, RAG, profiles, and sanitized Markdown/export behavior. Vitest handles Node 26's experimental web storage behavior internally. ## Source layout - `src/components/`: voice controls, chat, dialogs, profile, and account views. - `src/realtime/`: session lifecycle, observable application state, queue and budget handling, WebSocket protocol, tools, and external reasoning. - `src/audio/`: TypeScript capture/playback worklets, audio graph, PCM codec, and visualizer. Vite emits the worklets as separate JavaScript assets. - `src/lib/`: validated backend contracts, settings, prompt context, profile and report presentation, Markdown sanitization, and conversation exports. - `config/backend-proxy.ts`: the shared HTTP/WebSocket development proxy. - `src/styles.css`: Tailwind integration and React-specific layout adjustments. - `src/styles/legacy-theme.css`: the existing visual styles, retained for fidelity to both the white microphone and dark orb themes. The UI is ported to React; the full design has not been rewritten as Tailwind utilities. The current Spanish interface, local preference keys, session-only RAG, Markdown replies, JSON/TXT exports, optional browser wake word, TALK/TALKFIRST startup modes, and optional backend features are retained. Camera controls and quick actions remain absent, matching their disabled state in the old UI. Native speech stays at the current project's 16 kHz PCM rate. The backend continues to own VAD, transcription, model inference, synthesis, upstream credentials, and ApiPilot execution. Browser `SpeechSynthesis` is used only when the configured external reasoning service returns an answer instead of `log_only`. ## References - [Vite getting started](https://vite.dev/guide/) - [Vite server and proxy options](https://vite.dev/config/server-options) - [Vite features and asset handling](https://vite.dev/guide/features) - [Tailwind's Vite integration](https://tailwindcss.com/docs/installation/using-vite)