Nyx Documentations
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

Server Cluster Cryptography HTTPS REST WSS Realtime Pub/Sub & Presence Derives Encrypts Payload Web ClientReact + Zustand Hono API Servers PostgreSQLDrizzle ORM Redis Cluster Local Key Store

The server (Hono + Bun)

The server relies on the extremely fast Bun runtime and the Hono framework.

Core Design Principles

  1. 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).
  2. Stateless HTTP, Stateful WebSockets: Standard endpoints are completely stateless. WebSocket connections hold state (ChatConnectionState) in memory, but this state is synchronized globally via Redis.
  3. 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

POST /chat/messages Validate via Zod handleMessage() Persist Encrypted Payload emit('chat:message:created') Fanout to Room Subscribers Broadcast to Peers Return Success 200 OK Client Route Handler (Hono) Service Logic Postgres EventBus WebSocket/Redis

The Frontend (React + Web)

The frontend is built for responsiveness. It operates on a Local-First philosophy.

  1. 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.
  2. State Machine: The entire application state (conversations, messages, presence, typing indicators) is heavily managed by a global Zustand store (chat.store.ts), ensuring UI components remain thin and declarative.
  3. Connection Resilience: The websocket manager (chat.ws.ts) automatically handles connection drops, silent reconnections, and missed event reconciliation.

On this page