ui/ Bun workspace. It is a React 19 single-page application built with Vite and TypeScript, served by the same Bun monorepo that hosts the Effect-based backend. The UI exposes two distinct experiences: a customer-and-barista control room for order management, and a browser-side AI assistant that connects to the backend MCP server.
Tech stack
| Layer | Library / version |
|---|---|
| UI framework | React 19, TypeScript |
| Build tool | Vite 8 with @vitejs/plugin-react |
| Styling | Tailwind CSS 4 via @tailwindcss/vite |
| Component primitives | Radix UI (@radix-ui/react-dialog, @radix-ui/react-select, @radix-ui/react-progress, …) |
| High-level components | shadcn/ui conventions inside ui/src/shared/ui/retroui/ |
| Data fetching | TanStack Query v5 (@tanstack/react-query) |
| In-browser AI | @huggingface/transformers + onnxruntime-web |
| Effect runtime | effect 4.0.0-beta (used for async orchestration in the assistant) |
| Toast notifications | Sonner |
| Icons | Lucide React |
Feature areas
The app is split into two features underui/src/features/:
coffee-shop
The customer-and-barista control room. Handles menu display, order composition, real-time queue tracking, and per-ticket lifecycle actions. Served at
/control-room (alias /coffee-shop).assistant
The Browser Barista Brain. Loads LiquidAI’s LFM2.5-350M ONNX model in the browser over WebGPU, then lets the model call the backend MCP server for live coffee actions. Served at
/.App component (ui/src/app/App.tsx) performs a lightweight pathname switch — no router library is needed:
Running locally
Start the backend
The frontend dev server proxies
/api and /mcp to http://localhost:3000 by default, so the backend must be running first:Start the frontend dev server
ui/vite.shared.ts) registers two dev-server proxies:| Prefix | Proxy target |
|---|---|
/api | $VITE_COFFEE_PROXY_TARGET (default http://localhost:3000), path prefix stripped |
/mcp | $VITE_COFFEE_PROXY_TARGET, path kept as-is |
changeOrigin and WebSocket upgrade (ws: true).You can also start both the backend and the frontend together from the repo root with
bun run dev. Turborepo runs both tasks in parallel and reuses its .turbo cache on repeated runs.Storybook
Storybook 10 is configured atui/.storybook/ using @storybook/react-vite. It picks up all *.stories.{ts,tsx} files under ui/src/ and shares the same Vite configuration as the app build (Tailwind included).
Enabled addons: @storybook/addon-docs, @storybook/addon-a11y, @storybook/addon-vitest.
- From the monorepo root
- From the ui/ workspace
Portless subdomain routing
For HTTP-only local development without port numbers, the project shipsdev:onion:api and dev:onion:ui scripts that use Portless.
Start the backend on its subdomain
http://api.onion.localhost:1365.