Patchcord is currently a fully-functional IRC desktop client built with Next.js + Tauri. This roadmap outlines adding Matrix client support alongside IRC, with full feature parity including reactions, edits, encryption, and spaces.
- Solid existing architecture for chat client functionality
- Event system can be reused for Matrix events
- UI components (messages, channels, user lists) are mostly protocol-agnostic
- Rust has excellent Matrix SDK (
matrix-sdkcrate)
- Protocol differences: IRC is TCP/text-based; Matrix is HTTP/JSON-based with long-polling sync
- Different data models: IRC has simple channels; Matrix has rooms, events, state events, encryption
- Message history: Matrix stores all history server-side; requires sync tokens and pagination
- Authentication: Matrix uses access tokens with refresh flow
- Richer UI features: Reactions, edits, threading, encryption indicators, spaces
File: src-tauri/Cargo.toml
matrix-sdk = { version = "0.7", features = ["rustls-tls", "markdown", "image-proc"] }
matrix-sdk-indexeddb = "0.7" # For cross-platform storageFile: src-tauri/src/matrix.rs (NEW)
Key functions:
matrix_login- Login with homeserver URL, username, passwordmatrix_logout- Logout and clear tokensmatrix_sync- Long-polling sync loop with incremental updatesmatrix_join_room- Join a roommatrix_leave_room- Leave a roommatrix_send_message- Send text/markdown messagematrix_send_reaction- React to a messagematrix_edit_message- Edit a sent messagematrix_redact_message- Delete a messagematrix_get_rooms- List all roomsmatrix_get_room_messages- Paginated message historymatrix_upload_file- Upload attachmentsmatrix_search_rooms- Search/join public rooms
File: src-tauri/src/lib.rs
Add commands for each Matrix function (parallel to existing IRC commands).
- Reuse the existing
HashMap<String, Connection>pattern - Add separate HashMap for Matrix clients
- Implement secure token storage (access tokens, device IDs, sync tokens)
Extend the existing event system for Matrix:
Existing IRC events:
irc-eventwith types: status, privmsg, join, part, notice, names, etc.
Add Matrix events:
matrix-eventwith types:status- Connection status updatesmessage- New messages (text, image, file)reaction- Emoji reactions to messagesredaction- Message deletionsmembership- Join/leave/invite eventstyping- User typing indicatorsreceipt- Read receiptsnotification- Mention/notification eventsroom_state- Topic changes, avatar changes
The frontend can listen to both event streams and dispatch to shared UI components.
Files: Locate Zustand stores (likely src/lib/store.ts or similar)
Add Matrix state alongside IRC:
// Matrix-specific state
matrixHomeservers: Map<string, MatrixHomeserver>
matrixRooms: Map<string, MatrixRoom>
matrixMessages: Map<string, MatrixMessage[]>
matrixSyncTokens: Map<string, string>Create unified interfaces to support both protocols:
type ChatProtocol = 'irc' | 'matrix'
interface ChatServer {
id: string
protocol: ChatProtocol
name: string
connected: boolean
// IRC: server address
// Matrix: homeserver URL
}
interface ChatChannel {
id: string
serverId: string
protocol: ChatProtocol
name: string
topic?: string
unread: number
// Matrix-specific
encrypted?: boolean
directMessage?: boolean
}
interface ChatMessage {
id: string
channel: string
protocol: ChatProtocol
sender: string
senderAvatar?: string // Matrix only
content: string
timestamp: Date
// Matrix-specific
eventType?: 'm.room.message' | 'm.reaction' | 'm.room.redaction'
relatesTo?: string // For reactions/replies
edits?: string[] // Edit history
encrypted?: boolean
}This allows UI components to work with both IRC and Matrix.
Files: src/components/server-list.tsx or similar
Current: Shows IRC servers Add:
- Show both IRC servers and Matrix homeservers
- Different icons/indicators for protocol types
- Matrix-specific actions: explore rooms, spaces browser
- Connection status with latency
Files: src/components/channel-list.tsx or similar
IRC channels are simple. Matrix rooms need:
- Direct messages vs regular rooms (separate sections)
- Spaces (grouped rooms with hierarchy)
- Invite status badges
- Encryption indicators (lock icon)
- Unread message counts and highlights
- Room avatars
- Room topics
Files: src/components/message.tsx or similar
Matrix messages are richer than IRC:
Message types to support:
- Text with markdown formatting
- Code blocks with syntax highlighting
- Image thumbnails (click to expand)
- File attachments with download
- Replies (show original message)
- Reactions (emoji pills below message)
- Edit indicators ("edited" badge, show edit history)
- Redactions (show "message deleted" or remove)
- Verification badges for verified users
- Sender avatars
- Read receipts (who has read)
IRC vs Matrix differences:
- IRC: Simple text, colors, bold/italic
- Matrix: Structured event types, rich content, edits, reactions
Files: src/components/composer.tsx or similar
IRC: Simple text input Matrix needs:
- Markdown support (live preview)
- Emoji picker (for reactions and messages)
- File upload button
- Reply to message (show quoted message)
- Edit message mode
- Formatting toolbar (bold, italic, code, link)
- Attachment preview before sending
Files: src/app/settings.tsx or similar
Add Matrix settings section:
- Add/edit Matrix homeservers
- Homeserver URL (default: matrix.org)
- Login credentials (username/password)
- Room settings (default rooms to join)
- Notification preferences
- Encryption settings (verify devices, cross-signing)
- Sync settings (full sync vs lazy loading)
- Theme/customization per-homeserver
New component: src/components/spaces-browser.tsx
- Explore public rooms on homeserver
- Join spaces (room groups)
- Space hierarchy view
- Room directory with search/filter
Files: src/components/add-server-dialog.tsx or similar
Add Matrix-specific login:
- Homeserver URL input (with common presets)
- Username/password inputs
- Social login buttons (Google, Apple, GitHub - if homeserver supports)
- 2FA/OTP input if enabled
- Device name (for session management)
Matrix requires:
- Access token (long-lived)
- Refresh token (if using OIDC)
- Device ID
- Sync token (for incremental sync)
- Encryption keys (cross-signing keys)
Use Tauri's secure store or system keychain for storage.
New component: src/components/device-verification.tsx
- Show other devices logged into account
- Verify/unverify devices
- Cross-signing setup
- Recovery key setup
Matrix supports end-to-end encryption - this is complex but important.
Backend (matrix.rs):
- Enable encryption features in matrix-sdk
- Handle encrypted message sending/receiving
- Megolm key management
- Device verification flows
Frontend:
- Encryption indicators in room list and message composer
- Lock icons for encrypted rooms
- "Unverified device" warnings
- Shield icon for verified messages
- Setup encryption on first login
-
Testing Checklist:
- Login to matrix.org and other homeservers
- Join rooms, send/receive messages
- Test reactions, edits, deletions
- File uploads (images, documents)
- Encryption setup and encrypted rooms
- Spaces and room directory
- Notifications and mentions
- Cross-platform testing (Windows, macOS, Linux)
-
Edge Cases:
- Network reconnection handling
- Sync token corruption recovery
- Large room handling (thousands of messages)
- Slow connections
- Homeserver timeouts and errors
-
Performance:
- Lazy loading for room history
- Virtual scrolling for large message lists
- Optimized sync intervals
| File | Action |
|---|---|
src-tauri/Cargo.toml |
Add matrix-sdk dependency |
src-tauri/src/matrix.rs |
NEW - Matrix client implementation |
src-tauri/src/lib.rs |
Register Matrix Tauri commands |
src-tauri/capabilities/default.json |
Add Matrix command permissions |
| File/Pattern | Action |
|---|---|
src/lib/store.ts |
Add Matrix state management |
src/components/server-list.tsx |
Show both IRC and Matrix servers |
src/components/channel-list.tsx |
Handle Matrix rooms, spaces |
src/components/message.tsx |
Render Matrix messages (rich format) |
src/components/composer.tsx |
Markdown, edits, reactions |
src/components/spaces-browser.tsx |
NEW - Matrix spaces UI |
src/components/device-verification.tsx |
NEW - Encryption UI |
src/app/settings.tsx |
Add Matrix configuration |
- Week 1-2: Backend Matrix module (login, sync, basic messaging)
- Week 2: Event system integration
- Week 2-3: Frontend state refactoring (protocol-agnostic)
- Week 3-4: Basic UI (servers, rooms, text messages)
- Week 4-5: Rich features (reactions, edits, uploads)
- Week 5-6: Encryption and device verification
- Week 6-7: Spaces, testing, polish
- Login to matrix.org test server
- Join a room (e.g., #test:matrix.org)
- Send/receive text messages
- Message history persists across restarts
- React to messages with emoji
- Edit sent messages
- Delete/redact messages
- Upload and view images
- Reply to messages
- See typing indicators
- Create encrypted room
- Verify another device
- Send/receive encrypted messages
- See encryption indicators
- Use IRC and Matrix simultaneously
- Switch between IRC channels and Matrix rooms
- Notifications from both protocols
- Test on Windows
- Test on macOS
- Test on Linux
matrix-sdk- Official Matrix SDK for Rustmatrix-sdk-crypto- End-to-end encryptionmatrix-sdk-indexeddb- Cross-platform storage
- matrix.org - Official public server
- envs.net - Privacy-focused server
- libera.chat - IRC network with Matrix bridge
If full Matrix integration is too much work, consider an IRC-Matrix bridge:
- Run a bridge service (e.g., matrix-appservice-irc)
- Patchcord connects only to IRC
- Matrix rooms appear as IRC channels via the bridge
Pros: Much simpler (~1 week setup), no Matrix protocol code needed Cons: No Matrix-specific features (reactions, edits, encryption, etc.), depends on bridge service
This is a significant feature addition that will transform Patchcord into a multi-protocol chat client. The work is substantial but the existing architecture provides a solid foundation.
Estimated effort: 4-7 weeks for a polished, feature-complete Matrix integration.
The result will be a modern desktop chat client supporting both IRC (the classic developer chat protocol) and Matrix (the modern, encrypted, federated messaging protocol).