# restezzz/owncord architecture

> Architecture diagram of the GitHub repository restezzz/owncord, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/restezzz/owncord
- Repository: https://github.com/restezzz/owncord

## Overview

#### Purpose and Entry Points
OwnCord is a self-hosted real-time messenger supporting direct/group chat, uploads and voice notes, WebRTC calls, screen sharing, push notifications, and an optional Electron shell. The Node server is the authoritative API, persistence, signaling, and event hub: `server/src/index.js`, `server/src/socket.js`, `server/src/ioHub.js`. The browser client starts at `client/src/main.tsx` and composes the application in `client/src/App.tsx`. Electron launches the same web client/server deployment rather than maintaining local message state: `desktop/main.js`, `desktop/preload.js`.

#### Server HTTP, Authentication, and Security Boundary
Express exposes REST resources for identity, users, messages, groups, invites, mutes, push subscriptions, and health. Route modules form the HTTP boundary: `server/src/routes/auth.js`, `server/src/routes/messages.js`, `server/src/routes/groups.js`. Authentication and authorization are centralized around JWT/bcrypt and security policy in `server/src/auth.js` and `server/src/security.js`; admin, privacy, account deletion, and registration-invite rules are separate domain policies: `server/src/admin.js`, `server/src/privacy.js`, `server/src/invites.js`.

#### Persistence, Files, and Lifecycle Jobs
SQLite, accessed through `better-sqlite3`, is the durable source for accounts, conversations, messages, groups, and associated state: `server/src/db.js`. Upload handling is isolated at `server/src/uploads.js`, providing the boundary between HTTP/socket message operations and filesystem-backed attachments. Retention periodically removes expired messages and attachment files, while account deletion preserves conversation history under a deleted-user identity: `server/src/retention.js`, `server/src/accountDeletion.js`.

#### Realtime Messaging and Presence
Socket.IO delivers live conversation/group mutations, presence, and WebRTC signaling, while REST supplies durable reads and mutation endpoints. The server’s socket layer routes authenticated events through the shared IO hub: `server/src/socket.js`, `server/src/ioHub.js`; online/offline state is managed by `server/src/presence.js`. On the client, `client/src/socket.ts` maintains the realtime connection, `client/src/api.ts` handles HTTP calls, and `client/src/components/ChatPanel.tsx` / `client/src/components/MessageList.tsx` render and operate the active conversation.

#### Calls and WebRTC Signaling
Media remains peer-to-peer WebRTC; the server coordinates call state and relays signaling rather than transporting media. Direct-call lifecycle—including reconnect windows—is held in `server/src/callRegistry.js`; group session membership is tracked in `server/src/groupCallRegistry.js`. Client call orchestration owns media capture, peer connections, and signaling consumption: `client/src/hooks/useCall.ts`, `client/src/hooks/useGroupCall.ts`, `client/src/components/CallView.tsx`. Group calls use mesh topology, creating an explicit practical participant limit.

#### Client State and Product Shell
React state is organized by cross-cutting providers: authentication/configuration, groups, mutes, settings, and notifications in `client/src/context/AuthContext.tsx`, `client/src/context/GroupsContext.tsx`, and `client/src/context/SettingsContext.tsx`. Main screens divide unauthenticated and authenticated flows: `client/src/pages/Login.tsx`, `client/src/pages/Register.tsx`, `client/src/pages/Home.tsx`. Feature UI is component-driven, including group management and messaging attachments: `client/src/components/GroupModal.tsx`, `client/src/components/AttachmentMessage.tsx`, `client/src/components/VoiceRecorder.tsx`.

#### Delivery, Push, and Runtime Infrastructure
Production serves the built Vite client from the Node process; development runs Vite separately. The PWA surface includes a manifest and service worker: `client/public/manifest.webmanifest`, `client/public/sw.js`. Web Push spans server subscription/delivery logic and client registration utilities: `server/src/push.js`, `client/src/utils/push.ts`. Deployment targets a Node/systemd service behind nginx, with optional Dockerized TURN for restrictive NATs: `deploy/owncord.service`, `deploy/nginx.conf.example`, `deploy/turn/docker-compose.yml`. Electron adds native global shortcuts, auto-update, screen selection, and audio integration at the desktop boundary: `desktop/shortcuts.js`, `desktop/autoUpdater.js`, `desktop/screenPicker/picker.js`.

Main entry points: [`server/src/routes/messages.js`](https://github.com/restezzz/owncord/blob/main/server/src/routes/messages.js) (REST routes), [`client/src/App.tsx`](https://github.com/restezzz/owncord/blob/main/client/src/App.tsx) (App shell), [`client/src/hooks/useCall.ts`](https://github.com/restezzz/owncord/blob/main/client/src/hooks/useCall.ts) (Call orchestration), [`server/src/ioHub.js`](https://github.com/restezzz/owncord/blob/main/server/src/ioHub.js) (IO hub & presence)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_server["Node server"]
  node_server_entry["Server entry<br/>Node bootstrap<br/>[index.js]"]
  node_http_routes["REST routes<br/>Express boundary<br/>[messages.js]"]
  node_auth_security["Auth &amp; security<br/>JWT policy<br/>[auth.js]"]
  node_domain_policies["Account policies<br/>Domain policy<br/>[admin.js]"]
  node_database[("SQLite state<br/>better-sqlite3<br/>[db.js]")]
  node_uploads["Attachment storage<br/>Filesystem uploads<br/>[uploads.js]"]
  node_retention["Retention jobs<br/>Lifecycle worker<br/>[retention.js]"]
  node_socket_layer["Socket gateway<br/>Socket.IO boundary<br/>[socket.js]"]
  node_io_hub["IO hub &amp; presence<br/>Realtime coordination<br/>[ioHub.js]"]
end

subgraph group_client["Web client"]
  node_client_entry["React entry<br/>Vite entry<br/>[main.tsx]"]
  node_app_state["App providers<br/>React contexts<br/>[AuthContext.tsx]"]
  node_app_shell["App shell<br/>React composition<br/>[App.tsx]"]
  node_screens["Login &amp; home screens<br/>Page flows<br/>[Home.tsx]"]
  node_chat_ui["Chat interface<br/>Conversation UI<br/>[ChatPanel.tsx]"]
  node_client_api["HTTP client<br/>REST client<br/>[api.ts]"]
  node_client_socket["Realtime client<br/>Socket.IO client<br/>[socket.ts]"]
end

subgraph group_calls["Calling"]
  node_call_registry["Call registries<br/>Signaling state<br/>[callRegistry.js]"]
  node_call_client["Call orchestration<br/>WebRTC client<br/>[useCall.ts]"]
end

subgraph group_delivery["Delivery"]
  node_push["Web Push<br/>Push delivery<br/>[push.js]"]
  node_pwa["PWA worker<br/>Service worker<br/>[sw.js]"]
  node_production["Production edge<br/>systemd + nginx<br/>[owncord.service]"]
  node_turn["TURN service<br/>Docker NAT relay<br/>[docker-compose.yml]"]
end

subgraph group_desktop["Electron shell"]
  node_electron["Electron main<br/>Desktop host<br/>[main.js]"]
end

node_server_entry -->|"mounts"| node_http_routes
node_server_entry -->|"starts"| node_socket_layer
node_http_routes -->|"authorizes with"| node_auth_security
node_http_routes -->|"enforces"| node_domain_policies
node_http_routes -->|"reads and writes"| node_database
node_http_routes -->|"stores attachments"| node_uploads
node_socket_layer -->|"routes through"| node_io_hub
node_io_hub -->|"persists mutations"| node_database
node_io_hub -->|"coordinates calls"| node_call_registry
node_retention -->|"expires records"| node_database
node_retention -->|"removes files"| node_uploads
node_client_entry -->|"renders"| node_app_shell
node_app_shell -->|"provides state"| node_app_state
node_app_shell -->|"routes to"| node_screens
node_screens -->|"hosts"| node_chat_ui
node_chat_ui -->|"uses"| node_client_api
node_chat_ui -->|"receives live updates"| node_client_socket
node_client_api -->|"REST"| node_http_routes
node_client_socket -->|"Socket.IO"| node_socket_layer
node_call_client -->|"consumes signaling"| node_client_socket
node_call_client -->|"exchanges signaling"| node_call_registry
node_call_client -.->|"uses when needed"| node_turn
node_pwa -->|"registers subscription"| node_push
node_push -->|"subscription API"| node_http_routes
node_production -->|"runs"| node_server_entry
node_electron -->|"hosts"| node_app_shell

click node_server_entry "https://github.com/restezzz/owncord/blob/main/server/src/index.js"
click node_http_routes "https://github.com/restezzz/owncord/blob/main/server/src/routes/messages.js"
click node_auth_security "https://github.com/restezzz/owncord/blob/main/server/src/auth.js"
click node_domain_policies "https://github.com/restezzz/owncord/blob/main/server/src/admin.js"
click node_database "https://github.com/restezzz/owncord/blob/main/server/src/db.js"
click node_uploads "https://github.com/restezzz/owncord/blob/main/server/src/uploads.js"
click node_retention "https://github.com/restezzz/owncord/blob/main/server/src/retention.js"
click node_socket_layer "https://github.com/restezzz/owncord/blob/main/server/src/socket.js"
click node_io_hub "https://github.com/restezzz/owncord/blob/main/server/src/ioHub.js"
click node_client_entry "https://github.com/restezzz/owncord/blob/main/client/src/main.tsx"
click node_app_state "https://github.com/restezzz/owncord/blob/main/client/src/context/AuthContext.tsx"
click node_app_shell "https://github.com/restezzz/owncord/blob/main/client/src/App.tsx"
click node_screens "https://github.com/restezzz/owncord/blob/main/client/src/pages/Home.tsx"
click node_chat_ui "https://github.com/restezzz/owncord/blob/main/client/src/components/ChatPanel.tsx"
click node_client_api "https://github.com/restezzz/owncord/blob/main/client/src/api.ts"
click node_client_socket "https://github.com/restezzz/owncord/blob/main/client/src/socket.ts"
click node_call_registry "https://github.com/restezzz/owncord/blob/main/server/src/callRegistry.js"
click node_call_client "https://github.com/restezzz/owncord/blob/main/client/src/hooks/useCall.ts"
click node_push "https://github.com/restezzz/owncord/blob/main/server/src/push.js"
click node_pwa "https://github.com/restezzz/owncord/blob/main/client/public/sw.js"
click node_production "https://github.com/restezzz/owncord/blob/main/deploy/owncord.service"
click node_turn "https://github.com/restezzz/owncord/blob/main/deploy/turn/docker-compose.yml"
click node_electron "https://github.com/restezzz/owncord/blob/main/desktop/main.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server_entry,node_http_routes,node_auth_security,node_domain_policies,node_database,node_uploads,node_retention,node_socket_layer,node_io_hub toneBlue
class node_client_entry,node_app_state,node_app_shell,node_screens,node_chat_ui,node_client_api,node_client_socket toneAmber
class node_call_registry,node_call_client toneMint
class node_push,node_pwa,node_production,node_turn toneRose
class node_electron toneIndigo
```

## Components

### Node server

Authoritative API, event hub, and durable state.

- [Server entry](https://github.com/restezzz/owncord/blob/main/server/src/index.js): Node bootstrap · `server/src/index.js`
- [REST routes](https://github.com/restezzz/owncord/blob/main/server/src/routes/messages.js): Express boundary · Identity, messages, groups, invites, mutes, push, and health. · `server/src/routes/messages.js`
- [Auth & security](https://github.com/restezzz/owncord/blob/main/server/src/auth.js): JWT policy · `server/src/auth.js`
- [Account policies](https://github.com/restezzz/owncord/blob/main/server/src/admin.js): Domain policy · Admin, privacy, invite, and deletion rules. · `server/src/admin.js`
- [SQLite state](https://github.com/restezzz/owncord/blob/main/server/src/db.js): better-sqlite3 · Durable accounts, conversations, messages, and groups. · `server/src/db.js`
- [Attachment storage](https://github.com/restezzz/owncord/blob/main/server/src/uploads.js): Filesystem uploads · `server/src/uploads.js`
- [Retention jobs](https://github.com/restezzz/owncord/blob/main/server/src/retention.js): Lifecycle worker · Expires messages and attachment files. · `server/src/retention.js`
- [Socket gateway](https://github.com/restezzz/owncord/blob/main/server/src/socket.js): Socket.IO boundary · Authenticated realtime events and signaling. · `server/src/socket.js`
- [IO hub & presence](https://github.com/restezzz/owncord/blob/main/server/src/ioHub.js): Realtime coordination · `server/src/ioHub.js`

### Web client

React and PWA application.

- [React entry](https://github.com/restezzz/owncord/blob/main/client/src/main.tsx): Vite entry · `client/src/main.tsx`
- [App providers](https://github.com/restezzz/owncord/blob/main/client/src/context/AuthContext.tsx): React contexts · Authentication, groups, settings, mutes, and notifications. · `client/src/context/AuthContext.tsx`
- [App shell](https://github.com/restezzz/owncord/blob/main/client/src/App.tsx): React composition · `client/src/App.tsx`
- [Login & home screens](https://github.com/restezzz/owncord/blob/main/client/src/pages/Home.tsx): Page flows · Unauthenticated and authenticated product flows. · `client/src/pages/Home.tsx`
- [Chat interface](https://github.com/restezzz/owncord/blob/main/client/src/components/ChatPanel.tsx): Conversation UI · Renders active messages and sends mutations. · `client/src/components/ChatPanel.tsx`
- [HTTP client](https://github.com/restezzz/owncord/blob/main/client/src/api.ts): REST client · `client/src/api.ts`
- [Realtime client](https://github.com/restezzz/owncord/blob/main/client/src/socket.ts): Socket.IO client · `client/src/socket.ts`

### Calling

Server signaling coordination and peer media.

- [Call registries](https://github.com/restezzz/owncord/blob/main/server/src/callRegistry.js): Signaling state · Direct lifecycle and group session membership. · `server/src/callRegistry.js`
- [Call orchestration](https://github.com/restezzz/owncord/blob/main/client/src/hooks/useCall.ts): WebRTC client · Captures media and manages peer connections; group calls use mesh. · `client/src/hooks/useCall.ts`

### Delivery

Push and production runtime boundaries.

- [Web Push](https://github.com/restezzz/owncord/blob/main/server/src/push.js): Push delivery · Server subscriptions and client registration. · `server/src/push.js`
- [PWA worker](https://github.com/restezzz/owncord/blob/main/client/public/sw.js): Service worker · `client/public/sw.js`
- [Production edge](https://github.com/restezzz/owncord/blob/main/deploy/owncord.service): systemd + nginx · Serves built client through Node behind nginx. · `deploy/owncord.service`
- [TURN service](https://github.com/restezzz/owncord/blob/main/deploy/turn/docker-compose.yml): Docker NAT relay · Optional relay for restrictive NATs. · `deploy/turn/docker-compose.yml`

### Electron shell

Optional native host for the web deployment.

- [Electron main](https://github.com/restezzz/owncord/blob/main/desktop/main.js): Desktop host · Hosts the same web client/server deployment. · `desktop/main.js`

## Connections

- Server entry → REST routes: mounts
- Server entry → Socket gateway: starts
- REST routes → Auth & security: authorizes with
- REST routes → Account policies: enforces
- REST routes → SQLite state: reads and writes
- REST routes → Attachment storage: stores attachments
- Socket gateway → IO hub & presence: routes through
- IO hub & presence → SQLite state: persists mutations
- IO hub & presence → Call registries: coordinates calls
- Retention jobs → SQLite state: expires records
- Retention jobs → Attachment storage: removes files
- React entry → App shell: renders
- App shell → App providers: provides state
- App shell → Login & home screens: routes to
- Login & home screens → Chat interface: hosts
- Chat interface → HTTP client: uses
- Chat interface → Realtime client: receives live updates
- HTTP client → REST routes: REST
- Realtime client → Socket gateway: Socket.IO
- Call orchestration → Realtime client: consumes signaling
- Call orchestration → Call registries: exchanges signaling
- Call orchestration → TURN service: uses when needed
- PWA worker → Web Push: registers subscription
- Web Push → REST routes: subscription API
- Production edge → Server entry: runs
- Electron main → App shell: hosts
