slack-tui

command module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 14 Imported by: 0

README

slack-tui

A keyboard-first, vim-modal Slack client for your terminal.

Like vim or lazygit — not another Electron window. Built with Bubble Tea.

ci release license

slack-tui main view

Features

  • Vim-modal — NORMAL/INSERT modes, j/k, gg/G, Ctrl-d/u, / find, dd delete
  • Everything async — sends are optimistic, channels load in the background, the UI never freezes
  • Threads, reactions, edits — open threads, react with any emoji, edit and delete your messages
  • Autocomplete@ pops handles (mentions actually ping), : pops emoji
  • Fuzzy everything — command palette (Ctrl-K), workspace search (s), channel browser & join
  • Lives in the background — Socket Mode live unread (self-healing), terminal bell on mentions, unread count in the terminal title, ── new ── divider at first unread
  • 5 themes × 7 accents, group DMs, per-conversation drafts, multi-line composer
  • Mock workspace built in — run it with zero setup to try the feel
command palette mention autocomplete thread view

Install

Homebrew (macOS):

brew install kurenn/tap/slack-tui

Install script (macOS/Linux — verifies checksums, no Go needed):

curl -fsSL https://raw.githubusercontent.com/kurenn/slack-tui/main/install.sh | sh

Go:

go install github.com/kurenn/slack-tui@latest

go install puts the binary in $(go env GOPATH)/bin (usually ~/go/bin) — make sure that's on your PATH, then check with slack-tui --version.

…or grab a binary from the releases page.

slack-tui          # no token? you get a mock workspace to play with

Connect to Slack

  1. Create a Slack app from the manifest below (api.slack.com/apps → Create New AppFrom a manifest → paste it). It's also in the repo as JSON and YAML.
App manifest (JSON) — click to expand & copy
{
  "display_information": {
    "name": "slack-tui",
    "description": "A keyboard-first terminal Slack client",
    "background_color": "#0d1117"
  },
  "features": {
    "bot_user": {
      "display_name": "slack-tui",
      "always_online": false
    }
  },
  "oauth_config": {
    "redirect_urls": [
      "http://localhost:9899/callback"
    ],
    "scopes": {
      "user": [
        "channels:history",
        "channels:read",
        "channels:join",
        "groups:history",
        "groups:read",
        "im:history",
        "im:read",
        "mpim:history",
        "mpim:read",
        "users:read",
        "chat:write",
        "reactions:read",
        "reactions:write",
        "users:write",
        "dnd:write",
        "users.profile:write",
        "search:read"
      ],
      "bot": [
        "channels:history",
        "channels:read",
        "groups:history",
        "im:history",
        "mpim:history",
        "users:read"
      ]
    }
  },
  "settings": {
    "event_subscriptions": {
      "bot_events": [
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim"
      ]
    },
    "interactivity": {
      "is_enabled": false
    },
    "org_deploy_enabled": false,
    "socket_mode_enabled": true,
    "token_rotation_enabled": false
  }
}
  1. Sign in with your browser:
SLACK_CLIENT_ID=… SLACK_CLIENT_SECRET=… slack-tui login

…or pick "Sign in with Slack" in onboarding, or paste a user token (xoxp-…) directly. Tokens are stored in ~/.config/slack-tui/tokens.json (0600). Env vars (SLACK_USER_TOKEN, SLACK_APP_TOKEN, SLACK_BOT_TOKEN) override per-token.

For live channel unread, also generate an app-level token (xapp-…, Socket Mode) and invite the bot to the channels you care about — without it, unread badges refresh on a slow poll instead.

Keys

j/k gg/G Ctrl-d/u move · jump · half-page (arrows work too)
Tab h/l ←/→ switch panes
Enter / t open thread
i · r write · reply in thread
Alt-Enter newline in the composer
@… :… autocomplete mentions / emoji (Tab accepts)
a · e · dd · y react · edit · delete · yank
o open message links/files
/ n/N · s find in channel · search workspace
] [ next/prev unread
Ctrl-K command palette (fuzzy)
, · ? settings · help
Esc · q close/dismiss · quit

The mouse wheel scrolls. ? shows the full keymap in-app.

Development

go run .                          # mock workspace, no setup
go run . --dump 100x30            # render one frame to stdout (headless)
go run . --dump 100x30 "ctrl+k"   # …after replaying keys
go test ./...                     # hermetic — never touches the network

The architecture in one breath: internal/source abstracts the backend (a mock and a real Slack client behind one interface — network calls run inside tea.Cmds, never on the UI thread), internal/app is the Bubble Tea model with the modal keyboard engine, and internal/ui renders the panes.

License

MIT

Documentation

Overview

Command slack-tui is a keyboard-first terminal Slack client — a vim-modal three-pane chat client that runs inside your terminal like vim or lazygit. Data currently comes from a mock workspace; real Slack integration lands later.

Directories

Path Synopsis
internal
app
Package app is the root Bubble Tea model: navigation state, the modal NORMAL/INSERT keyboard engine (ported from tui-app.jsx's keydown router), and the View that composes the panes.
Package app is the root Bubble Tea model: navigation state, the modal NORMAL/INSERT keyboard engine (ported from tui-app.jsx's keydown router), and the View that composes the panes.
auth
Package auth implements Slack's browser OAuth (sign-in) flow for a local app: a loopback HTTP server catches the redirect, then the code is exchanged for tokens.
Package auth implements Slack's browser OAuth (sign-in) flow for a local app: a loopback HTTP server catches the redirect, then the code is exchanged for tokens.
config
Package config persists user preferences.
Package config persists user preferences.
data
Package data defines the workspace domain types and the mock workspace ported from the handoff's data.js.
Package data defines the workspace domain types and the mock workspace ported from the handoff's data.js.
markup
Package markup ports the handoff's renderText syntax tokenizer: it splits text on fenced ``` blocks and inline-tokenizes `code`, @mentions, #channels and urls, styling each with the palette's distinct hues.
Package markup ports the handoff's renderText syntax tokenizer: it splits text on fenced ``` blocks and inline-tokenizes `code`, @mentions, #channels and urls, styling each with the palette's distinct hues.
onboarding
Package onboarding is the first-run flow: a typewriter boot sequence, auth, a 5-step setup wizard with an interactive keyboard trainer, and a launch hand-off.
Package onboarding is the first-run flow: a typewriter boot sequence, auth, a 5-step setup wizard with an interactive keyboard trainer, and a launch hand-off.
root
Package root is the top-level Bubble Tea model.
Package root is the top-level Bubble Tea model.
source
Package source abstracts where workspace data comes from.
Package source abstracts where workspace data comes from.
theme
Package theme holds the five color palettes, accent overrides, and density settings ported from the design handoff's CSS custom properties.
Package theme holds the five color palettes, accent overrides, and density settings ported from the design handoff's CSS custom properties.
ui/components
Package components holds the presentational pieces of the app — sidebar, message list, thread rail, composer, title bar, status bar — ported from the handoff's tui-components.jsx.
Package components holds the presentational pieces of the app — sidebar, message list, thread rail, composer, title bar, status bar — ported from the handoff's tui-components.jsx.
ui/pane
Package pane renders the core visual primitive: a single-line box-drawing border with the title embedded in the top rule and an optional right-label, ported from the handoff's Pane component.
Package pane renders the core visual primitive: a single-line box-drawing border with the title embedded in the top rule and an optional right-label, ported from the handoff's Pane component.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL