# amiantos/lurker architecture

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

- Interactive diagram: https://gitdiagram.com/amiantos/lurker
- Repository: https://github.com/amiantos/lurker

## Overview

Lurker is a self-hosted, multi-user IRC bouncer with a web client and optional native-client integrations. The main workflow runs from a client connecting to the server, through persistent IRC network connections, to stored and synchronized chat history; users can search and manage that history from the UI. Separate product branches cover the built-in bouncer protocol, DCC, uploads and media previews, push notifications, and administration. The graph uses README feature descriptions and the shown source references; unsampled implementation details are represented only at directory level.

Main entry points: [`server/routes`](https://github.com/amiantos/lurker/tree/main/server/routes) (HTTP routes), [`vue_client/src/App.vue`](https://github.com/amiantos/lurker/blob/main/vue_client/src/App.vue) (Web client), [`server/services/ircManager.ts`](https://github.com/amiantos/lurker/blob/main/server/services/ircManager.ts) (IRC manager), [`server/services/engineLink.ts`](https://github.com/amiantos/lurker/blob/main/server/services/engineLink.ts) (Engine link)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client experience"]
  node_web["Web client<br/>[App.vue]"]
  node_client_api["Client API<br/>[api.ts]"]
  node_client_preview["Preview UI<br/>[useLinkPreview.ts]"]
end

subgraph group_server["Application server"]
  node_http_app["HTTP app<br/>[app.ts]"]
  node_http_routes["HTTP routes"]
  node_ws["WebSocket hub<br/>[wsHub.ts]"]
  node_admin["Admin storage<br/>[adminStorage.ts]"]
end

subgraph group_irc["IRC connectivity"]
  node_irc_manager["IRC manager<br/>[ircManager.ts]"]
  node_irc_connections["IRC connections<br/>[ircConnection.ts]"]
  node_bouncer["Built-in bouncer<br/>[bouncer.ts]"]
  node_engine_link["Engine link<br/>[engineLink.ts]"]
  node_engine_server["IRC engine<br/>[server.ts]"]
  node_engine_protocol["Engine protocol<br/>[protocol.ts]"]
end

subgraph group_data["Persistence and services"]
  node_database[("SQLite data<br/>[index.ts]")]
  node_search["Message search<br/>[searchRunner.ts]"]
  node_uploads["Upload service<br/>[uploadService.ts]"]
  node_upload_providers["Upload providers"]
  node_dcc["DCC transfers<br/>[dcc.ts]"]
  node_preview_service["Link previews<br/>[linkPreview.ts]"]
  node_push["Push service<br/>[pushService.ts]"]
  node_storage_stats["Storage attribution<br/>[storageStats.ts]"]
end

subgraph group_integrations["Optional integrations"]
  node_preview_container["Preview container"]
  node_push_relay["Push relay"]
end

node_user(("User"))
node_irc_networks(("IRC networks"))

node_user -->|"uses"| node_web
node_web -->|"requests"| node_client_api
node_client_api -.->|"calls API"| node_http_app
node_http_app -->|"mounts routes"| node_http_routes
node_http_routes -.->|"manages networks"| node_irc_manager
node_irc_manager -->|"uses connections"| node_irc_connections
node_irc_connections -.->|"connects to"| node_irc_networks
node_irc_manager -->|"stores history"| node_database
node_web -.->|"syncs chat"| node_ws
node_http_routes -.->|"searches history"| node_search
node_http_routes -.->|"handles uploads"| node_uploads
node_uploads -.->|"selects provider"| node_upload_providers
node_http_routes -.->|"serves DCC"| node_dcc
node_web -->|"resolves previews"| node_client_preview
node_client_preview -.->|"requests previews"| node_preview_service
node_preview_service -.->|"delegates previews"| node_preview_container
node_push -.->|"relays native push"| node_push_relay
node_admin -->|"collects attribution"| node_storage_stats
node_storage_stats -->|"reads storage data"| node_database
node_engine_link -->|"encodes frames"| node_engine_protocol
node_engine_server -->|"exchanges frames"| node_engine_protocol
node_engine_link -.->|"holds connections"| node_engine_server

click node_web "https://github.com/amiantos/lurker/blob/main/vue_client/src/App.vue"
click node_client_api "https://github.com/amiantos/lurker/blob/main/vue_client/src/api.ts"
click node_client_preview "https://github.com/amiantos/lurker/blob/main/vue_client/src/composables/useLinkPreview.ts"
click node_http_app "https://github.com/amiantos/lurker/blob/main/server/app.ts"
click node_http_routes "https://github.com/amiantos/lurker/tree/main/server/routes"
click node_ws "https://github.com/amiantos/lurker/blob/main/server/services/wsHub.ts"
click node_irc_manager "https://github.com/amiantos/lurker/blob/main/server/services/ircManager.ts"
click node_irc_connections "https://github.com/amiantos/lurker/blob/main/server/services/ircConnection.ts"
click node_bouncer "https://github.com/amiantos/lurker/blob/main/server/services/bouncer.ts"
click node_engine_link "https://github.com/amiantos/lurker/blob/main/server/services/engineLink.ts"
click node_engine_server "https://github.com/amiantos/lurker/blob/main/server/engine/server.ts"
click node_engine_protocol "https://github.com/amiantos/lurker/blob/main/server/engine/protocol.ts"
click node_database "https://github.com/amiantos/lurker/blob/main/server/db/index.ts"
click node_search "https://github.com/amiantos/lurker/blob/main/server/services/searchRunner.ts"
click node_uploads "https://github.com/amiantos/lurker/blob/main/server/services/uploadService.ts"
click node_upload_providers "https://github.com/amiantos/lurker/tree/main/server/services/uploadProviders"
click node_dcc "https://github.com/amiantos/lurker/blob/main/server/services/dcc.ts"
click node_preview_service "https://github.com/amiantos/lurker/blob/main/server/services/linkPreview.ts"
click node_push "https://github.com/amiantos/lurker/blob/main/server/services/pushService.ts"
click node_admin "https://github.com/amiantos/lurker/blob/main/server/routes/adminStorage.ts"
click node_storage_stats "https://github.com/amiantos/lurker/blob/main/server/db/storageStats.ts"

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_web,node_client_api,node_client_preview,node_user toneBlue
class node_http_app,node_http_routes,node_ws,node_admin toneAmber
class node_irc_manager,node_irc_connections,node_bouncer,node_engine_link,node_engine_server,node_engine_protocol toneMint
class node_database,node_search,node_uploads,node_upload_providers,node_dcc,node_preview_service,node_push,node_storage_stats toneRose
class node_preview_container,node_push_relay,node_irc_networks toneIndigo
```

## Components

### Client experience

- [Web client](https://github.com/amiantos/lurker/blob/main/vue_client/src/App.vue): `vue_client/src/App.vue`
- [Client API](https://github.com/amiantos/lurker/blob/main/vue_client/src/api.ts): `vue_client/src/api.ts`
- [Preview UI](https://github.com/amiantos/lurker/blob/main/vue_client/src/composables/useLinkPreview.ts): `vue_client/src/composables/useLinkPreview.ts`

### Application server

- [HTTP app](https://github.com/amiantos/lurker/blob/main/server/app.ts): `server/app.ts`
- [HTTP routes](https://github.com/amiantos/lurker/tree/main/server/routes): `server/routes`
- [WebSocket hub](https://github.com/amiantos/lurker/blob/main/server/services/wsHub.ts): `server/services/wsHub.ts`
- [Admin storage](https://github.com/amiantos/lurker/blob/main/server/routes/adminStorage.ts): `server/routes/adminStorage.ts`

### IRC connectivity

- [IRC manager](https://github.com/amiantos/lurker/blob/main/server/services/ircManager.ts): `server/services/ircManager.ts`
- [IRC connections](https://github.com/amiantos/lurker/blob/main/server/services/ircConnection.ts): `server/services/ircConnection.ts`
- [Built-in bouncer](https://github.com/amiantos/lurker/blob/main/server/services/bouncer.ts): `server/services/bouncer.ts`
- [Engine link](https://github.com/amiantos/lurker/blob/main/server/services/engineLink.ts): `server/services/engineLink.ts`
- [IRC engine](https://github.com/amiantos/lurker/blob/main/server/engine/server.ts): `server/engine/server.ts`
- [Engine protocol](https://github.com/amiantos/lurker/blob/main/server/engine/protocol.ts): `server/engine/protocol.ts`

### Persistence and services

- [SQLite data](https://github.com/amiantos/lurker/blob/main/server/db/index.ts): `server/db/index.ts`
- [Message search](https://github.com/amiantos/lurker/blob/main/server/services/searchRunner.ts): `server/services/searchRunner.ts`
- [Upload service](https://github.com/amiantos/lurker/blob/main/server/services/uploadService.ts): `server/services/uploadService.ts`
- [Upload providers](https://github.com/amiantos/lurker/tree/main/server/services/uploadProviders): `server/services/uploadProviders`
- [DCC transfers](https://github.com/amiantos/lurker/blob/main/server/services/dcc.ts): `server/services/dcc.ts`
- [Link previews](https://github.com/amiantos/lurker/blob/main/server/services/linkPreview.ts): `server/services/linkPreview.ts`
- [Push service](https://github.com/amiantos/lurker/blob/main/server/services/pushService.ts): `server/services/pushService.ts`
- [Storage attribution](https://github.com/amiantos/lurker/blob/main/server/db/storageStats.ts): `server/db/storageStats.ts`

### Optional integrations

- **Preview container**
- **Push relay**

### Other components

- **User**
- **IRC networks**

## Connections

- User → Web client: uses
- Web client → Client API: requests (evidence: `vue_client/src/App.vue`)
- Client API → HTTP app: calls API
- HTTP app → HTTP routes: mounts routes (evidence: `server/app.ts`)
- HTTP routes → IRC manager: manages networks
- IRC manager → IRC connections: uses connections (evidence: `server/services/ircManager.ts`)
- IRC connections → IRC networks: connects to
- IRC manager → SQLite data: stores history (evidence: `server/services/ircManager.ts`)
- Web client → WebSocket hub: syncs chat
- HTTP routes → Message search: searches history
- HTTP routes → Upload service: handles uploads
- Upload service → Upload providers: selects provider
- HTTP routes → DCC transfers: serves DCC
- Web client → Preview UI: resolves previews (evidence: `vue_client/src/composables/useLinkPreview.ts`)
- Preview UI → Link previews: requests previews
- Link previews → Preview container: delegates previews
- Push service → Push relay: relays native push
- Admin storage → Storage attribution: collects attribution (evidence: `server/routes/adminStorage.ts`)
- Storage attribution → SQLite data: reads storage data (evidence: `server/db/storageStats.ts`)
- Engine link → Engine protocol: encodes frames (evidence: `server/services/engineLink.ts`)
- IRC engine → Engine protocol: exchanges frames (evidence: `server/engine/server.ts`)
- Engine link → IRC engine: holds connections
