Appearance
Run locally
You need Node.js 18+ and pnpm 10.25+. npm and yarn are deliberately blocked by a preinstall check, so stick with pnpm.
First run
From the repository root:
bash
cp .env.example .env
pnpm installBring up Postgres and Redis (realtime pushes need both), then migrate and start the platform:
bash
docker compose --project-directory . -f docker/compose/docker-compose.dev.yml up -d postgres redis
pnpm --filter @repo/db migrate
pnpm devpnpm dev starts the platform apps through Turborepo, including the default workers process (realtime outbox worker on port 8792). Docs are separate — run pnpm docs:dev when you need the VitePress site on port 3003.
Ensure .env has DATABASE_URL and REDIS_URL (see .env.example). Without Redis, the API still boots but WebSocket realtime pushes will not work.
If you only need one surface, run it on its own:
bash
pnpm --filter web dev # player site, port 3000
pnpm --filter admin dev # admin panel, port 3001
pnpm --filter support dev # support desk, port 3002
pnpm --filter api dev # Hono API, port 8787
pnpm --filter workers dev # realtime outbox worker, port 8792Opt-in workers (analytics, notifier, customerio) stay on their own scripts — see environments.
Database
The platform expects PostgreSQL. Point DATABASE_URL at your instance in .env, then apply the schema:
bash
pnpm --filter @repo/db migrateThis creates (among other things) the private_state_* tables and realtime_event_outbox used by the realtime worker. Migrations 0086 (support_operator_users_fk) and 0087 (realtime_event_outbox) are required for support WebSocket events. Most migrations are generated from the Drizzle schema, but a few under packages/db/drizzle/ are hand-written SQL. If you change packages/db/src/schema, regenerate and review the diff with pnpm --filter @repo/db generate.
Redis and realtime worker
Redis backs one-time WebSocket tickets and cross-instance pub/sub for all private realtime topics (wallet balance, support, withdrawal, notification inbox). Local default:
bash
docker compose --project-directory . -f docker/compose/docker-compose.dev.yml up -d redisSet REDIS_URL=redis://127.0.0.1:6379 (or your compose password URL). The realtime worker is the workers package default (pnpm --filter workers dev / included in pnpm dev) and listens on port 8792. See Realtime messaging for architecture and verification (pnpm test:realtime-e2e).
Signing in to the admin panel
The admin panel only lets through users with an admin session, and the seeded superadmin role bypasses every permission check. Use a seeded or manually promoted admin account for your environment. If you are exploring a specific area, the access model lists which permission each page needs.
Payments in development
Crypto deposits go through CryptoCloud and fiat through Payou. Both rely on keys in .env and on webhooks that need a publicly reachable HTTPS URL, so end-to-end payment flows usually require a tunnel (or a staging environment) rather than plain localhost. Everything else — accounts, the lobby, segments, promotions — runs fine locally.
Handy commands
bash
pnpm lint # ESLint across the workspace
pnpm check-types # TypeScript across the workspace
pnpm test # Vitest in api, admin, wallet, auth, db, shared, clickhouse, streamer
pnpm docs:dev # these docs, on port 3003
pnpm docs:build # static build of these docs