Server
System Architecture
High-level overview of the Nyx distributed system
System Architecture
Nyx is designed to be a highly available, horizontally scalable chat system. It strictly separates transport (HTTP/WebSocket) from business logic, and uses Redis to bridge state across multiple server nodes.
High-Level Topology
The server (Hono + Bun)
The server relies on the extremely fast Bun runtime and the Hono framework.
Core Design Principles
- Route vs Service Separation: Hono controllers (
*.route.ts) are purely for input validation (via@hono/zod-openapi) and HTTP response formatting. All heavy lifting is delegated to standalone services (*.service.ts). - Stateless HTTP, Stateful WebSockets: Standard endpoints are completely stateless. WebSocket connections hold state (
ChatConnectionState) in memory, but this state is synchronized globally via Redis. - Event-Driven Internals: Core lifecycle events (like a user logging in, a message being saved, or a user joining a room) are dispatched via an internal
EventBus. This decouples the core logic from secondary effects like realtime fanout or push notifications.
Internal Request Flow
The Frontend (React + Web)
The frontend is built for responsiveness. It operates on a Local-First philosophy.
- Optimistic UI: When a user sends a message, it is instantly rendered in the chat view with a "pending" state. The UI does not wait for a server round-trip.
- State Machine: The entire application state (conversations, messages, presence, typing indicators) is heavily managed by a global
Zustandstore (chat.store.ts), ensuring UI components remain thin and declarative. - Connection Resilience: The websocket manager (
chat.ws.ts) automatically handles connection drops, silent reconnections, and missed event reconciliation.