Skip to main content

Architecture Overview

Chirp is built as a modern, full-stack application with a monorepo structure that combines React, Node.js, Electron, and PostgreSQL. This guide explains the technical architecture and design decisions that power the platform.

High-Level Architecture

graph TB
subgraph "Client Layer"
A[Web Browser] --> B[React Frontend]
C[Electron Desktop] --> B
D[Mobile / Capacitor] --> B
end

subgraph "Application Layer"
B --> E[Express.js API Server]
E --> F[Socket.IO Real-time]
end

subgraph "Business Logic"
E --> G[Authentication & AuthZ]
E --> H[File Processing]
E --> I[Message Handling]
F --> J[Presence & Events]
E --> V[Voice / WebRTC]
end

subgraph "Data Layer"
G --> K[PostgreSQL Database]
H --> L[File Storage]
I --> K
J --> K
K --> M[Redis Cache]
end

subgraph "External Services"
V --> T[Coturn TURN Server]
end

Core Technologies

Frontend Stack

  • React 19 — Modern UI framework with concurrent features
  • Vite — Fast build tool and development server
  • Tailwind CSS — Utility-first CSS framework
  • Zustand — Lightweight state management
  • TanStack Query — Server state management and caching
  • Socket.IO Client — Real-time communication
  • PeerJS / WebRTC — Voice channels

Backend Stack

  • Node.js — JavaScript runtime
  • Express.js — Web framework and API server
  • Socket.IO — Real-time bidirectional communication
  • PostgreSQL — Primary database
  • Redis — Caching and session management
  • Knex.js — SQL query builder and migration tool
  • JWT — Authentication tokens
  • Multer — File upload handling
  • Sharp — Image processing and thumbnails

Desktop & Mobile

  • Electron — Cross-platform desktop application
  • Electron Builder — Application packaging and distribution
  • Capacitor — Mobile app framework (Android)

System Components

1. Frontend Architecture

React Application Structure

src/renderer/
├── components/ # React components by feature
│ ├── ai/ # AI chat integration
│ ├── auth/ # Login, register, password reset
│ ├── category/ # Channel categories
│ ├── channel/ # Channel creation/management
│ ├── chat/ # Chat UI, link previews, polls
│ ├── collaborative/ # Real-time collaborative editing
│ ├── dev/ # Developer tools (theme panel)
│ ├── dm/ # Direct messages, group DMs
│ ├── events/ # Server events
│ ├── forum/ # Forum posts, tags
│ ├── friends/ # Friends system
│ ├── invite/ # Server invites
│ ├── layout/ # App layout, title bar, nav
│ ├── media/ # Media browser, folders
│ ├── moderation/ # Kick/ban modals
│ ├── routing/ # Route components
│ ├── server/ # Server settings, roles
│ ├── settings/ # User settings pages
│ ├── threads/ # Thread system
│ ├── ui/ # Shared UI (buttons, modals, pickers)
│ ├── user/ # User profiles
│ └── voice/ # Voice channel UI
├── hooks/ # Custom React hooks
│ ├── useAuth.js # Authentication logic
│ ├── useApi.js # API calls & TanStack Query
│ ├── useSocket.js # Socket.IO integration
│ ├── usePermissions.js # Permission checks
│ ├── useVoiceConnection.js # Voice channel WebRTC
│ ├── useAI.js # AI chat hook
│ └── ... (30+ hooks)
├── lib/ # Utility libraries
│ ├── api.js # API client (Axios)
│ ├── socket.js # Socket.IO client
│ ├── encryption.js # Client-side encryption
│ ├── aiService.js # LLM HTTP client
│ ├── platform.js # Platform detection
│ └── ... (25+ libs)
├── stores/ # Zustand state stores
│ ├── userStore.js # User/auth state
│ ├── messageStore.js # Message cache
│ ├── voiceStore.js # Voice channel state
│ ├── themeStore.js # Theme preferences
│ ├── unreadStore.js # Unread counts
│ ├── aiStore.js # AI settings
│ └── ... (25+ stores)
└── utils/ # Frontend utilities
├── queryGuard.js # Query error recovery
└── ...

State Management Strategy

Zustand for Client State:

  • User authentication status and profile
  • UI preferences and settings (themes, sounds)
  • Real-time presence information
  • Voice channel state
  • Unread message counts
  • Draft messages

TanStack Query for Server State:

  • API response caching
  • Automatic refetching and synchronization
  • Optimistic updates for messages
  • Loading and error state management

Query Guard System: The app includes a safety system (utils/queryGuard.js) that monitors critical queries (servers, channels, messages) and auto-recovers from empty cache states to prevent UI issues.

2. Backend Architecture

Express.js Server Structure

server/
├── routes/ # API endpoints (35+ route files)
│ ├── auth.js # Authentication routes
│ ├── users.js # User management
│ ├── servers.js # Server/guild management
│ ├── messages.js # Message handling
│ ├── directMessages.js # Direct messages
│ ├── groupDMs.js # Group direct messages
│ ├── media.js # Media upload/download
│ ├── forums.js # Forum channels
│ ├── collaborative.js # Collaborative channels
│ ├── webhooks.js # Webhook system
│ ├── roles.js # Role management
│ ├── moderation.js # Kick/ban/logs
│ ├── threads.js # Thread system
│ ├── search.js # Full-text search
│ ├── friends.js # Friends system
│ ├── reactions.js # Message reactions
│ ├── pins.js # Pinned messages
│ ├── emojis.js # Custom emoji
│ ├── stickers.js # Sticker packs
│ ├── events.js # Server events
│ ├── notes.js # User notes
│ ├── badges.js # User badges
│ ├── favorites.js # Favorites
│ ├── botTokens.js # Bot token management
│ ├── twoFactor.js # 2FA setup/verification
│ ├── admin.js # Admin endpoints
│ ├── webPush.js # Web push notifications
│ ├── fcm.js # Firebase Cloud Messaging (mobile)
│ ├── linkPreview.js # Link preview / oEmbed
│ └── ...
├── middleware/ # Express middleware
│ ├── auth.js # JWT authentication
│ └── ...
├── database/ # Database layer
│ └── migrations/ # Schema migrations
├── utils/ # Server utilities
├── socket.js # Socket.IO configuration
└── uploads/ # File storage directory

API Design Principles

RESTful Endpoints:

  • Clear resource-based URLs
  • Consistent HTTP status codes
  • Direct JSON responses (no wrapping envelope)
  • Bot token authentication support

Authentication Flow:

  • JWT-based stateless authentication
  • Token refresh with 30-day expiration
  • Two-factor authentication support (TOTP)
  • Bot tokens for API/WebSocket access
  • Permission-based authorization with role hierarchy

File Handling:

  • Multer for multipart uploads
  • Sharp for image processing and thumbnails
  • Support for images, videos, documents, audio, archives
  • Default 250MB upload limit

3. Real-time Architecture

Socket.IO Implementation

Server Side (server/socket.js):

// Authentication middleware verifies JWT or Bot token
io.use((socket, next) => {
// Verify token for socket connection
});

// On connection: join user rooms, server channels, group DMs
// Set user status to online

Real-time Features:

  • Presence status (online/idle/dnd/invisible/offline)
  • Typing indicators (channels, DMs, group DMs)
  • Live message creation, editing, deletion
  • Reaction updates
  • Read state synchronization across devices
  • Voice channel join/leave events
  • Server member updates
  • Poll vote events
  • Thread events

4. Voice Architecture

Chirp uses WebRTC with PeerJS for peer-to-peer voice communication:

  • Voice activity detection (VAD) for auto-mute
  • Optional noise suppression
  • Push-to-talk support
  • Per-user volume controls
  • Audio device selection
  • Coturn TURN server for NAT traversal (included in Docker setup)

5. Database Architecture

PostgreSQL Schema Design

Core Tables:

users              -- User accounts, profiles, settings
servers -- Discord-like servers/guilds
channels -- Text/voice/media/forum/collaborative channels
messages -- Channel messages with attachments
direct_messages -- Private messages
group_dm_messages -- Group DM messages
roles -- Permission roles
permissions -- Role-based permissions
reactions -- Message reactions
media_items -- Media channel content
forum_posts -- Forum channel posts
threads -- Message threading
friends -- Friend relationships
webhooks -- Channel webhooks
badges -- User badges
stickers -- Custom sticker packs
events -- Server events
notes -- User notes
pins -- Pinned messages

Key Design Patterns:

Hierarchical Permissions:

  • Role-based access control (RBAC)
  • Server-level and channel-specific permissions
  • Permission inheritance and overrides

Message Threading:

  • Threaded conversations within channels
  • Parent-child message relationships
  • Thread locking and auto-archiving

6. Security Architecture

Security Features:

  • JWT with configurable expiration
  • Password hashing with bcrypt
  • Two-factor authentication (TOTP with QR codes)
  • Input validation and sanitization
  • SQL injection prevention via Knex.js
  • Rate limiting on all endpoints
  • Bot token system separate from user auth

Encryption:

  • Client-side encryption for private channels
  • HTTPS in production
  • Secure WebSocket connections

Development Patterns

1. Optimistic Updates

TanStack Query Pattern:

// Update UI immediately
queryClient.setQueryData(['messages', channelId], (oldData) => {
return optimisticUpdate(oldData, newMessage);
});

// Then sync with server
await sendMessage(newMessage);

2. Query Optimization

Anti-Pattern Prevention:

  • Avoid broad invalidateQueries() calls (can cause empty UI)
  • Prefer targeted setQueryData() updates
  • Use refetchQueries with type: 'active'
  • Query guard system monitors critical data

3. IPC Pattern (Electron)

// Main process: ipcMain.handle() for async operations
// Renderer: ipcRenderer.invoke() for requests
// Main → Renderer: webContents.send() for events
// Preload: return cleanup functions from on* methods

Technology Rationale

Why React + Node.js?

  • Type consistency: JavaScript throughout the stack
  • Developer productivity: Fast development cycles
  • Ecosystem maturity: Rich library ecosystem
  • Real-time capabilities: Socket.IO integration

Why PostgreSQL?

  • ACID compliance: Data integrity guarantees
  • Complex queries: Advanced SQL features
  • Performance: Excellent read/write performance
  • Scalability: Supports complex scaling patterns

Why Electron?

  • Cross-platform: Single codebase for Windows/Mac/Linux
  • Web technology: Leverage existing web codebase
  • Native integration: File system, notifications, system tray
  • Auto-updates: Built-in update mechanism

Why Capacitor for Mobile?

  • Web-first: Reuse the React codebase
  • Native APIs: Access to push notifications, haptics, filesystem
  • Android support: Native Android app experience