logo
Architecture
Architecture

Architecture Overview

Colanode is built as two cooperating parts: a server that anchors persistence and coordination, and clients (web and desktop) that keep a complete working set locally for speed and resilience. The server authenticates users, stores data, runs background tasks, and broadcasts changes to connected devices. Clients read and write against a local SQLite database, synchronize changes in the background, and update the UI as soon as local state changes.

Architecture overview diagram

Server

The server is a Node.js API built with Fastify. It persists structured data in Postgres, uses Redis both as a cache and as the backing store for BullMQ job queues, and stores binary assets (uploads, attachments, media) in S3-compatible object storage. When a client submits a change, the server validates and writes it to Postgres, schedules any follow-up work through BullMQ, and then fans the confirmed change out to other devices in real time. This design keeps the API responsive while deferring heavier work—such as indexing, cleanup, or bulk fan-out—to background jobs.

Clients

Colanode runs on the web and on desktop with the same local-first behavior. The desktop app uses Electron with React and stores data in SQLite alongside the file system. The web app uses React with Web Workers and stores data in SQLite-wasm within the browser’s Origin Private File System. A single client can connect to multiple servers and accounts simultaneously, keeping each session’s data isolated while offering a unified experience in the UI.

Accounts, Workspaces, and Users

A server can authenticate many accounts and host many workspaces. An account may belong to multiple workspaces; when it joins a workspace, Colanode creates a distinct user identity with a unique ID scoped to that workspace. Each user belongs to exactly one workspace. This per-workspace user model simplifies authorization, auditing, and data partitioning without constraining how many workspaces an account may access.

Local-First Data Flow

On first login, the client performs a full sync for the selected workspaces and materializes the data into its local SQLite database. From that point on, all reads are served locally, and writes apply locally first for instant feedback. Every write is also appended to a local queue stored in a table named mutations. A background sync worker submits queued mutations to the server and reconciles responses back into the local database. If the network is unavailable or the server cannot be reached, the worker simply waits and resumes when connectivity returns. When a mutation cannot be confirmed after a configurable number of retries, the client reverts it to keep local state aligned with the authoritative server state (for example, an unsent message is removed).

Real-Time Updates

Each logged-in account maintains its own WebSocket connection to the server. When the server accepts and persists a mutation from any device, it broadcasts the resulting change to relevant clients over these sockets. Upon receiving a change, the client writes it into the local SQLite database and the UI updates reactively. This ensures low-latency interaction for the user while keeping devices consistent with each other.

Files and Blobs

Binary files are stored in S3-compatible object storage, while their metadata and references live in Postgres alongside other records. Clients treat file metadata like any other synced entity and fetch or cache content as needed, using the same background mechanisms that govern structured data.

While all structured data and entities (messages, pages, database records, and their metadata—are stored locally) file contents are downloaded on a per-need basis to optimize device storage. When a file is a previewable media type such as an image, audio, or video, the client downloads a local copy for preview and retains it for a limited period. If that file is not opened for seven days, the local copy is deleted to save space. Opening the file again automatically re-downloads it from the server. Users may also choose to download files manually to their device at any time