This project uses Bun as the package manager and runtime. Local API testing should use the standalone Bun server + Vite proxy, while production deployment can still target Vercel.
- Bun is required (version 1.3.5+)
- Use
bun installto install dependencies - Use
bun run <script>to run package.json scripts
# Development
bun run dev # Start full stack (API + Vite with proxy) — the default
bun run dev:vite # Start Vite dev server only (frontend-only, no API)
bun run dev:api # Start standalone Bun API server only (port 3000)
bun run dev:vercel # Optional: Vercel dev server (parity/debugging only)
# Build & Production
bun run build # TypeScript compile + Vite build
# Testing
bun test # Run all tests via bun:test (API tests require server running)
bun run test:unit # Unit/wiring tests only (no server needed)
bun run test:api # API integration tests onlyFor full functionality (default):
bun run devFor frontend-only development (no API):
bun run dev:viteFor API server only (e.g. to run tests against):
bun run dev:apiThe frontend runs on port 5173 by default. The standalone API defaults to port 3000.
The following environment variables are required for full functionality:
REDIS_KV_REST_API_URL- Upstash Redis REST API URL (for caching, chat rooms, authentication)REDIS_KV_REST_API_TOKEN- Upstash Redis REST API token
- AI provider API keys (at least one):
- OpenAI, Anthropic, or Google AI keys are configured via Vercel AI SDK
PUSHER_APP_ID- Pusher app ID (for chat rooms)PUSHER_KEY- Pusher keyPUSHER_SECRET- Pusher secretPUSHER_CLUSTER- Pusher cluster
ELEVENLABS_API_KEY- ElevenLabs API (for text-to-speech)YOUTUBE_API_KEY- YouTube Data API (for video metadata)YOUTUBE_API_KEY_2- YouTube Data API fallback keyOPENAI_API_KEY- OpenAI API (for audio transcription)
GOOGLE_GENERATIVE_AI_API_KEY- Google Generative AI (for machine translation of locale files)
Note: The application will run with limited functionality without these environment variables. API endpoints requiring these services will fail gracefully.
The project includes a .env.local file with all required keys pre-configured. Scripts that need API keys (e.g. scripts/machine-translate.ts) do not auto-load .env.local. Export the key before running:
export GOOGLE_GENERATIVE_AI_API_KEY="$(grep GOOGLE_GENERATIVE_AI_API_KEY .env.local | cut -d'"' -f2)"
bun run scripts/machine-translate.tsapi/- Node-style API route handlers (Vercel-compatible, also used by standalone Bun server)src/apps/- Individual application modules (Finder, TextEdit, Chats, etc.)public/- Static assets (fonts, icons, wallpapers, sounds)scripts/- Build and maintenance scripts
Tests use Bun's native test runner (bun:test). Test files live in tests/ and use the .test.ts extension.
# Run all tests (unit + API integration — requires API server running)
bun test
# Run only unit/wiring tests (no server required)
bun test tests/test-chat-notification-logic.test.ts tests/test-pusher-client-refcount.test.ts
# Run a single suite
bun test tests/test-admin.test.ts
# Run API integration tests only (requires server)
bun run test:api| Command | What it runs |
|---|---|
bun run test |
All tests (bun test) |
bun run test:api |
All API integration suites |
bun run test:unit |
All unit/wiring suites |
bun run test:new-api |
Auth, rooms, messages, presence |
bun run test:admin |
Admin endpoint |
bun run test:song |
Songs endpoints |
bun run test:ai |
AI endpoints (chat, applet-ai, ie-generate, ryo-reply) |
bun run test:media |
audio-transcribe, youtube-search |
bun run test:chat-wiring |
All chat wiring suites |
bun run test:pusher-regression |
All Pusher-related suites |
bun run test:chat-regression |
Chat + Pusher regression suites |
API integration tests require the standalone API server to be running:
# Terminal 1
bun run dev:api
# Terminal 2
bun test # all tests
bun run test:api # API integration only
bun test tests/test-admin.test.ts # single suiteTests use describe/test/expect from bun:test. Shared HTTP helpers are in tests/test-utils.ts:
fetchWithOrigin(url, opts)— addsOrigin: http://localhost:3000fetchWithAuth(url, username, token, opts)— adds Origin + Authorization + X-UsernamemakeRateLimitBypassHeaders()— random IP to avoid rate limits in testsensureUserAuth(username, password)— register-or-login, returns token
- Skip computer use / GUI-driven testing unless the user explicitly requests it
- When demoing UI changes or visual verification, prefer screenshots over video walkthroughs
- Only create video walkthroughs when the user explicitly asks for a video
- For most changes,
bun run buildis sufficient to verify the code compiles correctly - For API testing, use
bun run dev(full stack) orbun run dev:api+bun run dev:viteseparately - Only use the
computerUsesubagent for manual browser testing when the user specifically asks for visual verification or UI testing
- Linter warnings: The codebase has pre-existing linter warnings for unused variables. These are not blockers.
- Linting:
bun run lintmay still report pre-existing issues unrelated to your change. Check the current output before treating a lint failure as a regression. - API endpoints: API routes are Node-style handlers under
api/and require Redis for caching/storage. - Build process: The build generates service worker files (
sw.js,workbox-*.js) which are copied to.vercel/output/static/. - Vercel CLI: Installed globally, but optional for local testing now that standalone Bun API is available.
- Port conflicts: If port 3000 is occupied, set
API_PORT=<port>forbun run dev:apiand adjust proxy target accordingly.