A TypeScript monorepo for Zoff's SSR web, native mobile, television, Cast, and remote-control clients, built with pnpm workspaces.
apps/platform: The main web application for room management, queueing, and social interaction (SSR-enabled)apps/admin: Admin application served separately while preserving the admin route surfaceapps/cast: A standalone Chromecast Receiver application for synchronized playback on Google Cast devices (SSR-enabled)apps/embed: A standalone SSR embed player served at/embed/:roomNameby defaultapps/mobile: Native Expo application for iOS and Androidapps/remote: Lightweight web remote for controlling a paired Zoff screenapps/tv: Zoff TV, delivered as native Android TV and Samsung TV builds
packages/api: Type-safe API clientpackages/models: Shared domain types, interfaces, and validation schemaspackages/shared: Shared React hooks, utilities, and Zustand stores (includes safeWrap error handling)packages/ui: Shared UI through explicit@vibes/ui/web,@vibes/ui/native, and@vibes/ui/sharedplatform boundariespackages/serve: Shared TypeScript server, metrics, and tracing utilities
Use Node.js 26.8.1 or newer and pnpm 12.3.4, pinned in package.json.
The Docker build stages use the same pnpm version and install libatomic1,
which its native Linux executable requires on Debian slim images.
# Install dependencies
pnpm install
# Run the main platform app (port 3001, SSR-enabled)
pnpm dev
# Run all apps
pnpm --recursive dev
# Run the embed app (port 3006)
pnpm --filter @vibes/embed dev
# Run the native iOS/Android development server
pnpm --filter @vibes/mobile start
# Run the Android TV development server
pnpm --filter @vibes/tv start
# Run the Samsung TV browser-runtime preview
pnpm --filter @vibes/tv tizen:devSet EMBED_BASE_PATH in both apps/platform/.env and apps/embed/.env to
change the local embed mount path. Embed URLs accept the optional boolean query
parameters player, playlist, skip, and vote. Embedded playback always
requires an explicit visitor interaction.
For sender and receiver testing with a local API, PostgreSQL database, and Redis instance, see Local Cast development.
The React Router web applications support SSR for improved performance and SEO. Mobile is a native Expo application. Zoff TV shares its room/session behavior across two delivery targets: a native Android TV build and the browser runtime required by Samsung TVs.
- Platform App: SSR with room data prefetching
- Admin App: SSR for admin views
- Cast App: SSR for faster Chromecast loading
- Development: Hot module replacement with SSR
- Production: Optimized SSR builds
- Native: Expo Router on mobile and an Expo Android TV entrypoint
- Samsung TV: Vite packages the same TV product for Samsung's browser-based application runtime
- Linting & Formatting: Biome (
pnpm lint,pnpm fix) - Type Checking: TypeScript (
pnpm typecheck) - Testing: Vitest
- Error Handling:
safeWrap/safeWrapAsyncutilities (no try/catch) - Styling: Tailwind CSS v4 for DOM targets and NativeWind for React Native
- Dark Mode: System preference detection with manual toggle
- Error Handling: Safe error handling with
safeWraputilities - Type Safety: Full TypeScript with
@vibes/api - Real-time: SSE integration for live updates
- Cross-platform UI: Explicit web, native, and renderer-neutral package boundaries
Please read the AGENTS.md for non-negotiable frontend coding conventions and file layout rules.
