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, and each 1:1 DM shows a live presence dot — green when the person is online, hollow when away.
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. Other files (PDFs, video, audio, archives, …) show as clickable cards (name + size + a colour file-type icon). The icon is a small generated image (PDF/spreadsheet/doc/…) on image-capable terminals; without image support it falls back to a Nerd Font glyph or emoji — force the glyph style with[appearance] file_icons = nerdoremoji. Text snippets render as a code block. 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 = true, 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. - Day dividers between messages from different days (Today / Yesterday / date).
- Deleted messages stay in place with their original content kept and a dim
(deleted)marker by default; set[appearance] keep_deleted_messages = falseto drop them from the view instead. - 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 = true` to force, `false` to disable; unset = auto-detect).
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, which groups the selected message into its full burst of consecutive lines and includes the conversation around it) 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
Metadata
Release files for slak 26.6.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| slak-26.6.8.tar.gz | 180.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| slak-26.6.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 319.8 kB
Release files / slak-26.6.8.tar.gz
| Download URL | slak-26.6.8.tar.gz |
|---|---|
| Size | 180.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
842c53315e0180ffcd67893bde005aabf64201cbe47da6c6946beb62e35fd6ee
|
|
BLAKE2b-256 checksum How to use checksums |
026613b3959d876b557ea53a86b9583c3da5c606cb5450b5adc7fc55a810e823
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 30, 2026.
Transparency logRelease files / slak-26.6.8-py3-none-any.whl
| Download URL | slak-26.6.8-py3-none-any.whl |
|---|---|
| Size | 139.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8615a86ebe5086cefa119500234f39df52299d910ea1ec5fa21e559897df581d
|
|
BLAKE2b-256 checksum How to use checksums |
7492a87cf8e0f99143e17b1535fd9049c37f8fc83307a4df0b5fafe74de72851
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 30, 2026.
Transparency log