# ayn2op/discordo architecture

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

- Interactive diagram: https://gitdiagram.com/ayn2op/discordo
- Repository: https://github.com/ayn2op/discordo

## Overview

Discordo is a terminal client for Discord. The main workflow starts in the root UI, accepts a token from the environment or a login screen, then opens chat; chat presents guild/channel navigation and message interaction. Configuration and terminal rendering support that experience, while HTTP, TLS, and gateway packages provide Discord connectivity. The README documents password, QR, and token login. Some implementation excerpts are incomplete, so uncertain internal wiring is not shown.

Main entry points: [`internal/ui/root/model.go`](https://github.com/ayn2op/discordo/blob/main/internal/ui/root/model.go) (Root UI), [`internal/ui/chat/model.go`](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/model.go) (Chat UI), [`internal/ui/login`](https://github.com/ayn2op/discordo/tree/main/internal/ui/login) (Login screens), [`internal/ui/chat/messages_list.go`](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/messages_list.go) (Message list)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["Application UI"]
  node_cli["Command entry<br/>[root.go]"]
  node_root["Root UI<br/>[model.go]"]
end

subgraph group_auth["Authentication"]
  node_login["Login screens"]
  node_password["Password login"]
  node_qr["QR login<br/>[model.go]"]
  node_token["Token login<br/>[model.go]"]
  node_envtoken["Token environment"]
end

subgraph group_chat["Chat experience"]
  node_chatui["Chat UI<br/>[model.go]"]
  node_guildtree["Guild navigation<br/>[model.go]"]
  node_channelpicker["Channel picker<br/>[model.go]"]
  node_messages["Message list<br/>[messages_list.go]"]
  node_composer["Message composer<br/>[composer.go]"]
  node_attachments["Attachment picker<br/>[model.go]"]
  node_mentions["Mention list<br/>[model.go]"]
  node_markdown["Markdown renderer<br/>[renderer.go]"]
  node_state["Chat state<br/>[state.go]"]
end

subgraph group_services["Supporting services"]
  node_config["Configuration<br/>[config.go]"]
  node_keyring["Token storage<br/>[keyring.go]"]
  node_httpclient["HTTP client<br/>[client.go]"]
  node_tls["TLS client<br/>[client.go]"]
  node_gateway["Gateway client<br/>[gateway.go]"]
end

node_user(("Terminal user"))
node_discord{{"Discord service"}}

node_user -->|"starts client"| node_cli
node_cli -->|"loads settings"| node_config
node_cli -->|"starts UI"| node_root
node_user -->|"interacts"| node_root
node_root -->|"shows login"| node_login
node_login -->|"offers"| node_password
node_login -->|"offers"| node_qr
node_login -->|"offers"| node_token
node_user -->|"enters credentials"| node_password
node_user -->|"completes sign-in"| node_qr
node_user -->|"enters token"| node_token
node_envtoken -->|"provides token"| node_root
node_password -->|"returns token"| node_root
node_qr -->|"returns token"| node_root
node_token -->|"returns token"| node_root
node_root -->|"stores token"| node_keyring
node_root -->|"opens chat"| node_chatui
node_chatui -->|"presents navigation"| node_guildtree
node_chatui -->|"presents picker"| node_channelpicker
node_chatui -->|"presents messages"| node_messages
node_chatui -->|"presents composer"| node_composer
node_messages -->|"renders content"| node_markdown
node_messages -->|"offers attachments"| node_attachments
node_messages -->|"reads chat state"| node_state
node_composer -->|"uses suggestions"| node_mentions
node_chatui -->|"uses settings"| node_config
node_httpclient -->|"creates transport"| node_tls
node_httpclient -->|"sends API requests"| node_discord
node_gateway -->|"connects gateway"| node_discord

click node_cli "https://github.com/ayn2op/discordo/blob/main/cmd/root.go"
click node_root "https://github.com/ayn2op/discordo/blob/main/internal/ui/root/model.go"
click node_login "https://github.com/ayn2op/discordo/tree/main/internal/ui/login"
click node_password "https://github.com/ayn2op/discordo/tree/main/internal/ui/login"
click node_qr "https://github.com/ayn2op/discordo/blob/main/internal/ui/login/qr/model.go"
click node_token "https://github.com/ayn2op/discordo/blob/main/internal/ui/login/token/model.go"
click node_chatui "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/model.go"
click node_guildtree "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/guildstree/model.go"
click node_channelpicker "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/channelspicker/model.go"
click node_messages "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/messages_list.go"
click node_composer "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/composer.go"
click node_attachments "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/attachmentspicker/model.go"
click node_mentions "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/mentionslist/model.go"
click node_markdown "https://github.com/ayn2op/discordo/blob/main/internal/markdown/renderer.go"
click node_state "https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/state.go"
click node_config "https://github.com/ayn2op/discordo/blob/main/internal/config/config.go"
click node_keyring "https://github.com/ayn2op/discordo/blob/main/internal/keyring/keyring.go"
click node_httpclient "https://github.com/ayn2op/discordo/blob/main/internal/http/client.go"
click node_tls "https://github.com/ayn2op/discordo/blob/main/internal/tls/client.go"
click node_gateway "https://github.com/ayn2op/discordo/blob/main/internal/gateway/gateway.go"

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_cli,node_root,node_user toneBlue
class node_login,node_password,node_qr,node_token,node_envtoken toneAmber
class node_chatui,node_guildtree,node_channelpicker,node_messages,node_composer,node_attachments,node_mentions,node_markdown,node_state toneMint
class node_config,node_keyring,node_httpclient,node_tls,node_gateway toneRose
class node_discord toneIndigo
```

## Components

### Application UI

- [Command entry](https://github.com/ayn2op/discordo/blob/main/cmd/root.go): `cmd/root.go`
- [Root UI](https://github.com/ayn2op/discordo/blob/main/internal/ui/root/model.go): `internal/ui/root/model.go`

### Authentication

- [Login screens](https://github.com/ayn2op/discordo/tree/main/internal/ui/login): `internal/ui/login`
- [Password login](https://github.com/ayn2op/discordo/tree/main/internal/ui/login): `internal/ui/login`
- [QR login](https://github.com/ayn2op/discordo/blob/main/internal/ui/login/qr/model.go): `internal/ui/login/qr/model.go`
- [Token login](https://github.com/ayn2op/discordo/blob/main/internal/ui/login/token/model.go): `internal/ui/login/token/model.go`
- **Token environment**

### Chat experience

- [Chat UI](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/model.go): `internal/ui/chat/model.go`
- [Guild navigation](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/guildstree/model.go): `internal/ui/chat/guildstree/model.go`
- [Channel picker](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/channelspicker/model.go): `internal/ui/chat/channelspicker/model.go`
- [Message list](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/messages_list.go): `internal/ui/chat/messages_list.go`
- [Message composer](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/composer.go): `internal/ui/chat/composer.go`
- [Attachment picker](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/attachmentspicker/model.go): `internal/ui/chat/attachmentspicker/model.go`
- [Mention list](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/mentionslist/model.go): `internal/ui/chat/mentionslist/model.go`
- [Markdown renderer](https://github.com/ayn2op/discordo/blob/main/internal/markdown/renderer.go): `internal/markdown/renderer.go`
- [Chat state](https://github.com/ayn2op/discordo/blob/main/internal/ui/chat/state.go): `internal/ui/chat/state.go`

### Supporting services

- [Configuration](https://github.com/ayn2op/discordo/blob/main/internal/config/config.go): `internal/config/config.go`
- [Token storage](https://github.com/ayn2op/discordo/blob/main/internal/keyring/keyring.go): `internal/keyring/keyring.go`
- [HTTP client](https://github.com/ayn2op/discordo/blob/main/internal/http/client.go): `internal/http/client.go`
- [TLS client](https://github.com/ayn2op/discordo/blob/main/internal/tls/client.go): `internal/tls/client.go`
- [Gateway client](https://github.com/ayn2op/discordo/blob/main/internal/gateway/gateway.go): `internal/gateway/gateway.go`

### Other components

- **Terminal user**
- **Discord service**

## Connections

- Terminal user → Command entry: starts client
- Command entry → Configuration: loads settings
- Command entry → Root UI: starts UI
- Terminal user → Root UI: interacts
- Root UI → Login screens: shows login
- Login screens → Password login: offers
- Login screens → QR login: offers
- Login screens → Token login: offers
- Terminal user → Password login: enters credentials
- Terminal user → QR login: completes sign-in
- Terminal user → Token login: enters token
- Token environment → Root UI: provides token
- Password login → Root UI: returns token
- QR login → Root UI: returns token
- Token login → Root UI: returns token
- Root UI → Token storage: stores token
- Root UI → Chat UI: opens chat
- Chat UI → Guild navigation: presents navigation
- Chat UI → Channel picker: presents picker
- Chat UI → Message list: presents messages
- Chat UI → Message composer: presents composer
- Message list → Markdown renderer: renders content
- Message list → Attachment picker: offers attachments
- Message list → Chat state: reads chat state
- Message composer → Mention list: uses suggestions
- Chat UI → Configuration: uses settings
- HTTP client → TLS client: creates transport
- HTTP client → Discord service: sends API requests
- Gateway client → Discord service: connects gateway
