Jabber is social app currently in development. Build rooms create posts, follow people, and keep the conversation flowing.
apps/api: Go + Chi + Postgres API with JWT authapps/web: TanStack Router + React Query + Tailwind UI
- Install deps:
pnpm run install:all
- Start Postgres:
docker compose up -d
- Apply schema:
export DATABASE_URL="postgres://postgres:postgres@localhost:5432/jabber?sslmode=disable"pnpm run migrate:up
- Configure env:
cp apps/api/.env.example apps/api/.env
- Run API:
pnpm run dev:api
- Run web:
pnpm run dev:web
POST /api/v1/auth/registerPOST /api/v1/auth/loginGET /api/v1/me(requiresAuthorization: Bearer <token>)
GET /api/v1/posts(optionalAuthorization: Bearer <token>)POST /api/v1/posts(requiresAuthorization: Bearer <token>)POST /api/v1/posts/:postID/vote(requiresAuthorization: Bearer <token>, body{ "value": 1 | -1 | 0 })
- WebSocket:
GET /api/v1/rooms/:roomID/ws(requiresAuthorization: Bearer <token>or?token=...)- Example client URL:
ws://localhost:8080/api/v1/rooms/lobby/ws?token=<jwt>
- Example client URL:
Message protocol (JSON):
- Client → Server:
{ "type": "join", "payload": { "role": "speaker" | "listener" } }{ "type": "offer", "sdp": "<sdp>" }{ "type": "candidate", "candidate": { "candidate": "<ice>", "sdpMid": "audio", "sdpMLineIndex": 0 } }
- Server → Client:
{ "type": "answer", "sdp": "<sdp>" }{ "type": "candidate", "candidate": { "candidate": "<ice>", "sdpMid": "audio", "sdpMLineIndex": 0 } }