A terminal Slack client built on Textual
Project description
slak
A terminal Slack client built on Textual.
Unofficial. Uses Slack's internal browser protocol and may violate Slack's TOS. Not affiliated with Slack Technologies, LLC.
Features
Keyboard-first. Borderless Textual UI — workspace rail, channel sidebar, message
pane, compose. The compose box is focused on launch, so you just start typing. Tab
cycles focus, Ctrl+P opens the command palette (every action), and F1 shows the
full keybinding reference.
Workspaces & navigation
- Multiple workspaces with concurrent live connections;
Alt+1…Alt+9jump,Ctrl+Wopens a filterable switcher. Ctrl+Kfuzzy channel/DM finder — also lists public channels you haven't joined (marked· join) and joins one on selection;Alt+←/Alt+→walk channel history;Ctrl+Btoggles the sidebar,Ctrl+Tthe thread panel.- Drag the dividers between the channel list / messages / thread to resize them; the widths are remembered across restarts.
- Cache-first startup: your last context renders instantly while sync runs behind it.
Messaging
- Send, edit (
Ctrl+E), and delete messages; reactions (Ctrl+R); threads with a follow-the-cursor reply panel. Ctrl+Nnew-message composer (DM and group DM);@/:mention & emoji autocomplete;Ctrl+Oopens link(s) in a message;Spacepreviews image attachments.- In-channel (
Ctrl+F) and workspace-wide (Ctrl+Shift+F) search. - Typing indicators, both directions.
Sidebar
- Slack-native sections (
users.channelSections.list, linked-list order) with a pinned★ Starredsection, or config-glob sections ([sections.<name>]) as a fallback — grouped, collapsible, live-updated on section/star events. - A
⚑ Threadsrow opens the threads view (your subscribed threads, newest-reply first). DM and group-DM names are resolved to member display names.
Rendering
- Slack markdown, mentions, custom emoji (inline images on kitty), fenced code blocks (rendered literally on a tinted block), and Block Kit / legacy attachments (headers, sections, fields, context, dividers, controls).
- Inline images for files and attachments — kitty graphics on kitty,
▀half-blocks on any truecolor terminal. Spacepreviews the selected message's image full-screen. Default is an in-terminal preview (works over SSH); set[appearance] image_preview = guito open it in an external viewer on the local machine instead.- Colour themes (13 built-in incl. a true-black
oledand terminal-followingansi-dark/ansi-light, plus~/.config/slak/themes/*.tomland[theme]overrides), switched live withCtrl+Y; the sidebar is auto-kept contrasting (CIELAB). - Optional user avatars beside messages (
[appearance] avatars = on, off by default) — rendered as 4×2 half-blocks in a left gutter. - Optional coloured author names (
[appearance] colored_names = true, off by default) — each author name and@mentiontinted by a deterministic hash of the user id. - Local nicknames —
Ctrl+Gon a message renames its author just for you (stored by user id in[nicknames]); the nickname shows everywhere that name does. - Optional author grouping (
[appearance] group_within_minutes = N, 0 = off) — consecutive messages from the same author within N minutes drop the repeated name/timestamp header (and avatar), so a back-and-forth reads as a block. - Private channels show a padlock — the single-width `` glyph when an installed
font covers it (Nerd Font / FontAwesome, detected via fontconfig), else a narrow
⚿fallback (`[appearance] nerd_font = auto|on|off`).
Realtime & integration
- RTM with exponential-backoff reconnection and missed-history backfill.
- Desktop notifications, presence/DND, terminal tab-title unread indicator.
- Opt-in embedded MCP server (
[mcp] enabled = true) — an AI client reads your context (slak_get_context) and drafts a reply (slak_set_draft, draft-only). Run the adapter withslak --mcp(pip install 'slak[mcp]').
Underneath: a pluggable SlackClient (browser-cookie auth, with an in-memory fake
for offline/dev), a self-healing SQLite cache (WAL + FTS5), and round-trippable TOML
config. ~340 tests.
Not yet wired: the sixel image protocol (half-blocks cover non-kitty terminals).
Install
Recommended — pipx installs it isolated and puts slak
on your PATH globally:
pipx install slak
pipx install 'slak[mcp]' # with the optional MCP adapter
Or with pip (ideally in a virtualenv):
pip install slak
Debian / Ubuntu (.deb)
Requires Ubuntu 24.04 (Noble) or newer — slak needs Python ≥ 3.12, which 24.04 is the first Ubuntu LTS to ship (22.04 has 3.10 and is not supported).
A pre-built .deb is attached to each release;
it bundles slak + all deps in a private venv under /usr/lib/slak and depends only
on python3.12 (apt pulls it automatically):
sudo apt install ./slak_<version>_noble_amd64.deb
slak
To build one yourself (run on the same release you install on — the bundle is tied to that release's Python minor version and CPU architecture):
packaging/build-deb.sh # -> dist/slak_<version>_<arch>.deb
sudo apt install ./dist/slak_*.deb
Remove with sudo apt remove slak.
Nix
A flake is provided:
nix run github:Frodotus/slak # run without installing
nix profile install github:Frodotus/slak
nix develop # dev shell with deps + pytest
Either way you get a slak command.
First run
Just run it:
slak
On the first launch (no workspace configured yet) slak opens a short setup
wizard that walks you through copying your Slack browser session — an xoxc-…
token and the d cookie — from https://app.slack.com via DevTools. Credentials
are stored locally and sent only to Slack. After that, slak connects to your
workspace automatically.
slak # your workspace (runs the setup wizard on first launch)
slak --add-workspace # run the wizard again to add another workspace
slak --list-workspaces
slak --demo # explore a seeded demo workspace (no account needed)
(slak with no workspace in a non-interactive shell — CI/cron — prints setup
instructions and exits rather than prompting; use --demo there.)
Develop
python3 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
python -m slak --demo # run against a seeded demo workspace
textual run --dev slak/dev.py # run with live CSS hot-reload
textual console # (separate terminal) stream logs
pytest # run the test suite
The look is themeable CSS — edit slak/ui/styles/app.tcss while running under
--dev to restyle instantly.
Versioning
Releases use calendar versioning YY.M.N — two-digit year, month (not
zero-padded), and the Nth release that month. For example the third release in
June 2026 is 26.6.3. scripts/bump_version.py derives the next version from the
date and existing tags and writes it to pyproject.toml and slak/version.py.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slak-26.6.1.tar.gz.
File metadata
- Download URL: slak-26.6.1.tar.gz
- Upload date:
- Size: 166.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf7fef2b9e1bbad16170d5deca25d1191edad433ac3ba5bd4259ddfb226328a4
|
|
| MD5 |
8524800870a20eb8cd4f48509c1cf935
|
|
| BLAKE2b-256 |
f0bb456ec47e408200be64d48f55615671c75f4aa7904058c3e4aa015a55526a
|
Provenance
The following attestation bundles were made for slak-26.6.1.tar.gz:
Publisher:
release.yml on Frodotus/slak
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slak-26.6.1.tar.gz -
Subject digest:
cf7fef2b9e1bbad16170d5deca25d1191edad433ac3ba5bd4259ddfb226328a4 - Sigstore transparency entry: 1910182574
- Sigstore integration time:
-
Permalink:
Frodotus/slak@abc13aa151c3a39940d8eefa3d9f7905dda02e76 -
Branch / Tag:
refs/tags/v26.6.1 - Owner: https://github.com/Frodotus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@abc13aa151c3a39940d8eefa3d9f7905dda02e76 -
Trigger Event:
push
-
Statement type:
File details
Details for the file slak-26.6.1-py3-none-any.whl.
File metadata
- Download URL: slak-26.6.1-py3-none-any.whl
- Upload date:
- Size: 129.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
002970ae6ae2760a324a11a43312a6b788ac43af8e8da07d2a816fd1b1cd45dd
|
|
| MD5 |
4996804acf068ae07650050764127223
|
|
| BLAKE2b-256 |
9c2f97cb475c9f796b2ff3a9760bf379b341dd51ab79c643702e9d4106e3bb97
|
Provenance
The following attestation bundles were made for slak-26.6.1-py3-none-any.whl:
Publisher:
release.yml on Frodotus/slak
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slak-26.6.1-py3-none-any.whl -
Subject digest:
002970ae6ae2760a324a11a43312a6b788ac43af8e8da07d2a816fd1b1cd45dd - Sigstore transparency entry: 1910182682
- Sigstore integration time:
-
Permalink:
Frodotus/slak@abc13aa151c3a39940d8eefa3d9f7905dda02e76 -
Branch / Tag:
refs/tags/v26.6.1 - Owner: https://github.com/Frodotus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@abc13aa151c3a39940d8eefa3d9f7905dda02e76 -
Trigger Event:
push
-
Statement type: