TUI client for Slack written in Go
- Go 99.6%
- Makefile 0.4%
| internal | ||
| .gitignore | ||
| config.example.yaml | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| Makefile | ||
| README.md | ||
Slackr
A keyboard-driven terminal UI client for Slack, built in Go with Bubble Tea.
Browse channels and DMs, read and send messages, reply in threads, react with emoji, search, and get live updates over Slack's real-time API — all without leaving the terminal.
┌ workspace ───┐┌ #general ───────────────────────────────────┐
│ #general (3) ││ alice 09:34 │
│ #random ││ morning all 👋 │
│ 🔒 launch ││ bob 09:36 │
│ @carol ││ ▌ deploy is green, shipping now │
│ ... ││ :tada: 2 ↳ 3 replies (t to open) │
└──────────────┘└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ ┃ Message... (Enter to send, Esc to cancel) │
└─────────────────────────────────────────────┘
↵ open tab next pane / search ^r refresh ? help q quit
Features
- Sidebar of channels, private channels, group DMs and direct messages, sorted and grouped, with unread counts.
- Scrollable message pane with resolved usernames,
@mentionexpansion, emoji-reaction summaries and thread reply counts. - Compose box: send messages to the current conversation.
- Threads: open any message's thread, read replies, and reply inline.
- Reactions: add an emoji reaction to the selected message.
- Search: full-text message search; jump straight to a result's conversation.
- Live updates: new messages stream in over the RTM websocket; conversations are marked read as you view them.
Requirements
- Go 1.22 or newer.
- A Slack user OAuth token (
xoxp-...).
Getting a token
Slackr authenticates as you, using a user token. Create one via a Slack app:
- Go to https://api.slack.com/apps → Create New App → From scratch.
- Under OAuth & Permissions, add these User Token Scopes:
channels:read,groups:read,im:read,mpim:read— list conversationschannels:history,groups:history,im:history,mpim:history— read messageschat:write— send messagesreactions:write— add reactionsusers:read— resolve display namessearch:read— message search
- Install to Workspace and copy the User OAuth Token (
xoxp-...).
Slackr never sends your token anywhere except Slack's own API.
Configuration
Provide the token in any of these ways (checked in order):
-
SLACKR_TOKENenvironment variable -
SLACK_TOKENenvironment variable -
~/.config/slackr/config.yaml:token: xoxp-your-token-here history_limit: 80 # messages fetched per conversation (optional)
Build & run
git clone https://forge.quinlan.cloud/joshquinlan/slackr.git
cd slackr
go mod tidy # fetch dependencies
go build -o slackr .
SLACK_TOKEN=xoxp-... ./slackr
Or install onto your PATH:
go install forge.quinlan.cloud/joshquinlan/slackr@latest
Keybindings
| Key | Action |
|---|---|
Tab / Shift+Tab |
Cycle panes (sidebar → messages → compose) |
←/h, →/l |
Jump to sidebar / messages |
↑/k, ↓/j |
Move selection |
g / G |
Top / bottom |
Enter (sidebar) |
Open conversation |
Enter (messages) |
Focus the compose box |
Enter (compose) |
Send message |
t |
Open thread on the selected message |
r |
Add an emoji reaction |
R |
Mark conversation read |
/ |
Search messages |
Ctrl+R |
Refresh conversations & history |
Esc |
Close modal / leave compose |
? |
Help |
q / Ctrl+C |
Quit |
Project layout
slackr/
├── main.go # entrypoint: config load + Bubble Tea program
├── internal/
│ ├── config/ # token & settings loading
│ ├── slack/ # slack-go wrapper → plain domain structs
│ └── ui/ # Bubble Tea model, update, view, styles, keys
└── README.md
The UI layer never touches the Slack SDK directly: internal/slack exposes
Conversation, Message, Reaction and friends, so the TUI stays decoupled
from the transport.
Notes & limitations (v1)
- Reads/sends as your user account via the Web API; real-time receive uses RTM.
- Canvases, huddles, workflow tools and file uploads are out of scope for v1.
- Message editing/deleting is not yet wired up (reactions and threads are).
License
MIT