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 Web] --> 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]
end

subgraph "Data Layer"
G --> K[PostgreSQL Database]
H --> L[File Storage]
I --> K
J --> K
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

Backend Stack

  • Node.js - JavaScript runtime
  • Express.js - Web framework and API server
  • Socket.IO - Real-time bidirectional communication
  • PostgreSQL - Primary database
  • Knex.js - SQL query builder and migration tool
  • JWT - Authentication tokens
  • Multer - File upload handling

Desktop Platform

  • Electron - Cross-platform desktop application framework
  • Electron Builder - Application packaging and distribution

System Components

1. Frontend Architecture

React Application Structure

src/renderer/
├── components/ # Reusable UI components
│ ├── auth/ # Authentication components
│ ├── chat/ # Chat interface
│ ├── forum/ # Forum features
│ ├── media/ # Media browsing
│ └── common/ # Shared components
├── hooks/ # Custom React hooks
│ ├── useAuth.js # Authentication logic
│ ├── useApi.js # API calls
│ ├── useSocket.js # Socket.IO integration
│ └── usePermissions.js # Permission checks
├── lib/ # Utility libraries
│ ├── api.js # API client
│ ├── socket.js # Socket client
│ └── encryption.js # Client-side encryption
├── stores/ # Zustand state stores
│ ├── authStore.js # Authentication state
│ ├── messageStore.js # Message cache
│ └── uiStore.js # UI state
└── utils/ # Frontend utilities
├── queryGuard.js # Query error recovery
└── formatters.js # Data formatting

State Management Strategy

Zustand for Client State:

  • User authentication status
  • UI preferences and settings
  • Real-time presence information
  • Temporary UI state (modals, forms)

TanStack Query for Server State:

  • API response caching
  • Automatic refetching and synchronization
  • Optimistic updates
  • 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
│ ├── auth.js # Authentication routes
│ ├── users.js # User management
│ ├── servers.js # Server/guild management
│ ├── channels.js # Channel operations
│ ├── messages.js # Message handling
│ └── media.js # Media upload/download
├── middleware/ # Express middleware
│ ├── auth.js # JWT authentication
│ ├── uploads.js # File serving
│ └── errorHandler.js # Error handling
├── database/ # Database layer
│ ├── migrations/ # Schema migrations
│ └── seeds/ # Sample data
├── utils/ # Server utilities
│ ├── crypto.js # Encryption helpers
│ ├── thumbnails.js # Image processing
│ └── permissions.js # Permission logic
├── socket.js # Socket.IO configuration
└── uploads/ # File storage directory

API Design Principles

RESTful Endpoints:

  • Clear resource-based URLs
  • HTTP status codes for responses
  • Consistent response format
  • Versioning support via URL prefixes

Authentication Flow:

  • JWT-based stateless authentication
  • Refresh token rotation
  • Two-factor authentication support
  • Permission-based authorization

File Handling:

  • Multer for multipart uploads
  • Sharp for image processing and thumbnails
  • File type validation and security scanning
  • Organized storage structure

3. Real-time Architecture

Socket.IO Implementation

Server Side (server/socket.js):

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

// Event handlers
socket.on('join-server', (serverId) => {
// Join server room and update presence
});

socket.on('message-typing', (data) => {
// Broadcast typing indicator
});

Client Side (hooks/useSocket.js):

// Auto-reconnect with exponential backoff
// Presence management
// Message broadcasting
// Typing indicators
// Real-time notifications

Real-time Features:

  • Presence status (online/offline/away)
  • Typing indicators
  • Live message updates
  • Notification delivery
  • Server/channel member updates

4. Database Architecture

PostgreSQL Schema Design

Core Tables:

users              -- User accounts and profiles
servers -- Discord-like servers/guilds
channels -- Text/media/forum channels
messages -- Channel messages
direct_messages -- Private messages
roles -- Permission roles
permissions -- Role-based permissions
reactions -- Message reactions
media_items -- Media channel content
forum_posts -- Forum channel posts
threads -- Message threading

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-specific permissions

Audit Trail:

  • User activity logging
  • Message editing history
  • Permission change tracking

5. Security Architecture

Authentication & Authorization

Multi-layer Security:

graph LR
A[Client Request] --> B[JWT Verification]
B --> C[Permission Check]
C --> D[Resource Access]

B --> E[Token Refresh]
C --> F[Rate Limiting]
D --> G[Audit Logging]

Security Features:

  • JWT with short-lived access tokens
  • Secure refresh token rotation
  • Password hashing with bcrypt
  • Two-factor authentication (TOTP)
  • Input validation and sanitization
  • SQL injection prevention via Knex.js
  • File upload security scanning

Data Protection

Encryption:

  • Client-side encryption for private channels
  • Database encryption at rest (configurable)
  • HTTPS-only in production
  • Secure cookie handling

Privacy:

  • User data isolation
  • Read permissions enforcement
  • Audit logging for administrative actions
  • Data export and deletion capabilities

Development Patterns

1. Monorepo Structure

The project uses a workspace-based monorepo:

Benefits:

  • Shared dependencies and configuration
  • Atomic commits across frontend/backend
  • Simplified development workflow
  • Consistent tooling and standards

Challenges:

  • Larger repository size
  • Complex build processes
  • Dependency management overhead

2. API-First Development

Pattern:

  1. Design API endpoints first
  2. Create frontend mockups
  3. Implement backend logic
  4. Connect frontend to real API
  5. Add real-time features

Benefits:

  • Clear contract between frontend/backend
  • Parallel development possible
  • Easier testing and validation

3. Optimistic Updates

TanStack Query Pattern:

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

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

Benefits:

  • Instant UI feedback
  • Better perceived performance
  • Graceful error handling

4. Query Optimization

Anti-Pattern Prevention:

  • Avoid broad invalidateQueries() calls
  • Prefer targeted setQueryData() updates
  • Use refetchQueries with type: 'active'
  • Implement query guard for critical data

Performance Considerations

Frontend Optimization

  • React 19 concurrent features
  • Virtual scrolling for large message lists
  • Image lazy loading and thumbnails
  • Code splitting and lazy loading
  • Service worker for offline support

Backend Optimization

  • Database indexing for common queries
  • Connection pooling
  • Response caching
  • File compression and CDN usage
  • Rate limiting and DDoS protection

Database Optimization

  • Proper indexing strategy
  • Query performance monitoring
  • Connection pooling
  • Read replicas for scaling

Scalability Architecture

Horizontal Scaling Ready

  • Stateless API server design
  • Database connection pooling
  • File storage can be externalized
  • Socket.IO adapter for multi-instance deployment

Deployment Patterns

  • Docker containerization
  • Environment-specific configurations
  • Database migration system
  • Blue-green deployment support

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 integration
  • Auto-updates: Built-in update mechanism

Future Architecture Considerations

Potential Enhancements

  • Microservices: Split into specialized services
  • GraphQL: More flexible API queries
  • WebSocket replacement: Consider modern alternatives
  • Database sharding: Horizontal data scaling
  • CDN integration: Global content delivery

Migration Paths

  • Cloud services: AWS/GCP managed services
  • Container orchestration: Kubernetes deployment
  • Database scaling: Read replicas and sharding
  • File storage: S3-compatible object storage

This architecture provides a solid foundation for a scalable, maintainable social platform while keeping development complexity manageable.