End-to-end encrypted chat. Keys are generated and never leave the client.
- Next.js 16 · React 19 · Tailwind v4
- Socket.io for real-time messaging
- TanStack Query for server state
- ECDH + AES-GCM for E2E encryption via Web Crypto API
- pnpm workspaces monorepo
apps/
web/ Next.js app
packages/
shared/ Encryption logic, API types, Zod schemas
ui-tokens/ Design tokens — CSS variables + typed TS constants
ui-web/ React component library (consumes ui-tokens)
pnpm install
pnpm --filter web dev- On register — an ECDH key pair is derived from the user's passphrase via PBKDF2, the private key is AES-GCM wrapped and stored server-side, the public key is stored in plaintext.
- On login — the wrapped private key is fetched and unwrapped in-browser using the passphrase. The raw private key never touches the server.
- Messages are encrypted client-side with the recipient's public key before sending. The server stores and forwards ciphertext only.
Zero dependencies. Exports CSS custom properties (tokens.css) and typed TS constants for colors, spacing, and typography. Consumed by ui-web and imported directly into globals.css.
React component library. No business logic — all data hooks and crypto stay in apps/web. Components receive data and handlers as props. Tailwind classes are scanned from apps/web via @source in globals.css.
Shared between web and any future API package. Contains the encryption primitives, Zod schemas, and TypeScript types that both sides agree on.
- Add
apps/mobile(Expo) - Add
packages/ui-native— same component API asui-web, rendered withStyleSheet packages/sharedandpackages/ui-tokens(TS constants only) are already cross-platform