wrappers/rest-api/tools/react-viewer/README.md
A modern React-based web UI for RealSense Cameras, leveraging the REST API backend.
../../)You need two terminals running in parallel — one for the backend (FastAPI) and one for the frontend (Vite dev server). Each terminal has a one-time install step followed by a long-running server. The install steps below assume you start from the repo root.
cd wrappers/rest-api
python3 install.py # one-time: installs requirements (and pyrealsense2 if missing)
python3 main.py # long-running: serves the API on http://localhost:8000
install.py installs the packages from requirements.txt and, if pyrealsense2 is
not already importable, also pulls it from PyPI (skipped if you already have it
installed locally — built from source, apt, or pip).
cd wrappers/rest-api/tools/react-viewer
npm install # one-time: installs Node dependencies
npm run dev # long-running: serves the UI on http://localhost:3000
If npm is not installed:
sudo apt install npm
You only need this step if you want to enable the AI chat assistant in Agent
mode (the Ask mode uses Kapa.ai and works without any key). The viewer itself
runs fine without a .env file — the chat icon will just show "AI Assistant
unavailable" until a key is provided.
Step 1 — make sure you are in the React viewer folder (this is where both
.env.example and the dev server live):
cd wrappers/rest-api/tools/react-viewer
Step 2 — copy .env.example to .env (same content, different filename so the
viewer picks up your local settings without overwriting the template):
# Linux / macOS
cp .env.example .env
# Windows PowerShell
Copy-Item .env.example .env
:: Windows cmd.exe
copy .env.example .env
Step 3 — get an API key from one provider:
Step 4 — open .env in any text editor and fill in the value(s):
For Groq (the default), uncomment / set the first line:
VITE_GROQ_API_KEY=gsk_xxxxxxxxxxxxxxxxxxxxxxxx
For OpenAI, uncomment that line instead and paste your sk-... key. For a custom
provider, set VITE_LLM_API_URL, VITE_LLM_API_KEY and VITE_LLM_MODEL. You can
also override the backend URL via VITE_API_URL if FastAPI is on a different host.
Step 5 — restart npm run dev so Vite reloads the new env values (Vite only
reads .env* files at startup).
The .env file is git-ignored — your key never gets committed.
The procedure is the same on Windows, Linux, and macOS apart from the file-copy command in step 1. Editing and the key-provider sign-up are identical across platforms.
Once both terminals are up (backend on :8000, frontend on :3000), navigate to
http://localhost:3000. The frontend proxies API calls to the
backend automatically.
react-viewer/
├── src/ # React app (TypeScript)
│ ├── api/ # Backend clients (REST, Socket.IO, WebRTC, chat)
│ ├── components/ # React components
│ │ └── ChatBot/ # AI chat UI (Ask + Agent modes)
│ ├── store/ # Zustand state management
│ └── utils/ # Helpers (e.g. AI prompt builder)
├── src-tauri/ # Tauri desktop bridge (Rust)
│ ├── src/ # Rust sources
│ ├── icons/ # App icons (reused from common/res)
│ └── resources/
├── public/ # Static assets (favicon, logos)
├── scripts/ # Build helpers (e.g. bundle-for-prod)
└── tests/ # Vitest unit + Playwright E2E tests
├── unit/
├── e2e/
├── mocks/ # MSW handlers + fixtures
├── setup/ # Vitest global setup
└── utils/ # Test helpers
| Command | Description |
|---|---|
npm run dev | Start development server with hot reload |
npm run build | Build for production |
npm run preview | Preview production build locally |
npm run lint | Run ESLint |
npm run bundle | Copy build to FastAPI static folder |
npm test: Run unit and integration tests (Vitest)npm run test:coverage: Generate coverage report (HTML/LCOV)npm run test:e2e: Run Playwright E2E tests (headless)npx playwright installSee detailed instructions in tests/README.md.
Build a standalone cross-platform desktop app for Windows, macOS, and Linux that bundles both the React UI and the FastAPI backend into a single installer.
For Tauri dev mode (hot-reload window for the desktop app), see the Development Workflow section in DESKTOP_BUILD.md.
A one-shot build script is provided for both Windows and Linux/macOS. It runs all three stages (PyInstaller → Vite → Tauri bundle) and produces platform-native installers.
Linux / macOS:
cd wrappers/rest-api/tools/react-viewer
chmod +x build-all.sh
./build-all.sh # build everything
./build-all.sh --clean # clean + rebuild
Windows (PowerShell):
cd wrappers\rest-api\tools\react-viewer
.\build-all.ps1 # build everything
.\build-all.ps1 -Clean # clean + rebuild
Both scripts produce, under the repository root:
build/rest-api-dist/realsense_api/ - PyInstaller bundle of the FastAPI backendbuild/tauri-target/release/bundle/ - native installer(s):
.msi + .exe (NSIS).deb + .AppImage.dmgPrerequisites: Node.js 18+, Python 3.8+, Rust 1.56+ (https://rustup.rs/), PyInstaller
(pip install pyinstaller).
Linux distro support (Tauri 1.5). This project currently uses Tauri 1.5, which links against WebKitGTK 4.0:
| Ubuntu LTS | Codename | Desktop build (Tauri) |
|---|---|---|
| 20.04 | Focal | ✅ Native build |
| 22.04 | Jammy | ✅ Native build (recommended) |
| 24.04 | Noble | ❌ Not supported with Tauri 1.5 (4.0 headers removed; the symlink hack passes pkg-config but the wry crate then fails to compile against the 4.1 API) |
| 26.04 | Resolute | ❌ 4.0 packages no longer shipped |
Ubuntu 24.04 / 26.04 users: the desktop installer build (
build-all.sh) cannot currently produce a working binary on these distros. Use the two-terminal dev setup described in Quick Start instead — it works on every Ubuntu version. That gives you the full viewer running locally (FastAPI on:8000, React on:3000in the browser); you just don't get a packaged.AppImage/.deb.
Migration to Tauri 2 — planned as a future improvement, and the path that will
unblock Ubuntu 24.04+ desktop builds. Tauri 2 links against WebKitGTK 4.1 and builds
natively on those distros. The migration is medium effort (half a day for an
experienced dev): bump tauri / tauri-build / wry, run npm run tauri migrate to
auto-rewrite ~70 % of tauri.conf.json and the JS API imports, then fix residual
compile errors and re-test the FastAPI subprocess spawn.
Linux only — Tauri build dependencies. The Rust bundler needs WebKitGTK and a few other dev headers. On Debian/Ubuntu:
sudo apt install -y \
libwebkit2gtk-4.0-dev libgtk-3-dev libsoup2.4-dev \
libayatana-appindicator3-dev librsvg2-dev libssl-dev \
pkg-config build-essential
If build-all.sh fails with failed to get cargo metadata or cargo: command not found, your shell does not have cargo on PATH. After installing Rust via
rustup, enable it in the current shell with:
source $HOME/.cargo/env
To make this permanent, add the same line to ~/.bashrc. The build script also
attempts this automatically if it detects cargo is missing.
For Tauri internals (architecture, subprocess management, config reference), manual build steps, dev mode and troubleshooting, see DESKTOP_BUILD.md.
Build the React app:
npm run build
npm run bundle
This copies the build to ../rest-api/static/
Add static file serving to main.py:
from fastapi.staticfiles import StaticFiles
# Add at the end, after all API routes
app.mount("/", StaticFiles(directory="static", html=True), name="static")
Run FastAPI server - it will serve both API and UI:
python main.py
The viewer connects to the REST API at /api/v1/:
GET /devices - List connected devicesGET /devices/{id}/sensors - Get device sensorsPUT /devices/{id}/sensors/{sid}/options/{oid} - Update camera optionPOST /devices/{id}/streams/start - Start streamingPOST /webrtc/offer - WebRTC signalingReal-time data is received via Socket.IO on the /socket path.
Apache License 2.0 - See the main librealsense repository for details.