https://github.com/sorokin-vladimir/tele
Keyboard-first Telegram client for the terminal, written in Go
https://github.com/sorokin-vladimir/tele
cli cross-platform go golang keyboard-driven linux macos messenger tele telegram telegram-client terminal terminal-ui tui vim-like
Last synced: about 9 hours ago
JSON representation
Keyboard-first Telegram client for the terminal, written in Go
- Host: GitHub
- URL: https://github.com/sorokin-vladimir/tele
- Owner: sorokin-vladimir
- License: gpl-3.0
- Created: 2026-05-08T20:29:19.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-25T10:17:03.000Z (1 day ago)
- Last Synced: 2026-06-25T12:08:47.822Z (about 24 hours ago)
- Topics: cli, cross-platform, go, golang, keyboard-driven, linux, macos, messenger, tele, telegram, telegram-client, terminal, terminal-ui, tui, vim-like
- Language: Go
- Homepage:
- Size: 5.96 MB
- Stars: 108
- Watchers: 3
- Forks: 13
- Open Issues: 52
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: .github/SECURITY.md
Awesome Lists containing this project
- awesome-starred - sorokin-vladimir/tele - Keyboard-first Telegram client for the terminal, written in Go (Go)
README
# tele
```
_ _
| |_ ___ | | ___
| __| / _ \ | | / _ \
| |_ | __/ | | | __/
\__| \___| |_| \___|
```
> A terminal-native Telegram client built for keyboard-driven workflows.
[](https://go.dev)
[](LICENSE)
[](https://github.com/sorokin-vladimir/tele/releases)
[](#installation)
Features •
Installation •
Why tele? •
Keybindings •
Roadmap
---

> **Status:** Active development — already usable for daily messaging (private chats, groups, replies, reactions, forwarding, drafts). Some Telegram features are still in progress.
---
## Why tele?
Telegram Desktop, the web client, and mobile apps are designed around mouse-first interaction.
If you live in the terminal — using tools like Neovim, yazi, k9s, or tmux — switching to a GUI messenger breaks your flow.
`tele` keeps you in the terminal.
It is built for:
- keyboard-driven navigation
- fast chat switching
- SSH / remote workflows
- distraction-free messaging
If tools like lazygit feel natural to you, `tele` will too.
It also runs lean — typically ~35MB RSS at idle vs several hundred MB for desktop clients.
---
| Feature | tele | Telegram Desktop | Web |
| -------------------- | ----------------------- | ---------------- | ---------- |
| Terminal-native | ✅ | ❌ | ❌ |
| Keyboard-first | ✅ | ⚠️ partial | ⚠️ partial |
| Works over SSH | ✅ | ❌ | ❌ |
| Single static binary | ✅ | ❌ | ❌ |
| Full media support | ⚠️ photos, voice, video | ✅ | ✅ |
| Voice/video calls | ❌ out of scope¹ | ✅ | ✅ |
| Record voice / круж. | ❌ out of scope¹ | ✅ | ✅ |
> ¹ **Architectural constraint.** `tele` is a terminal-native, cgo-free client
> with no access to a microphone or camera capture stack. Recording voice
> messages or round videos (кружки) — and real-time voice/video calls — fall
> outside that design and are not planned. You can still **send** an
> already-recorded audio or video file from disk (see [attaching media](#keybindings)).
---
## Features
### ⚡ Keyboard-first UX
Vim-inspired navigation (`j/k`, `gg/G`, insert mode, etc.), plus a movable
per-message cursor (`ctrl+j/k`) that steps bubble-by-bubble, stays centered as
the chat scrolls, and is the target for the context menu and per-message actions.
### 💬 Full Telegram support
Private chats, groups, channels, replies, reactions, edits, forwarding, and
per-chat drafts synced with Telegram (saved on the server, shared across devices).
### 🎞 Rich media in the terminal
- **Photos** — rendered inline in high quality via the Kitty graphics protocol, with an ANSI block-art fallback; press `o` to open in an external viewer.
- **Voice messages** — amplitude waveform with duration, and **in-app playback** (`p`) with an animated playhead. Fully cgo-free on every platform: Opus/Ogg is decoded in pure Go, and audio goes out via `oto` (macOS/Windows) or the PulseAudio/PipeWire protocol (Linux). On Linux this needs a running PulseAudio or PipeWire server (the desktop default).
- **Video & round video (кружки)** — inline thumbnail preview with a `▶` / duration overlay (round notes shown as a circle); press `o` to play in the system player.
- **GIFs** — inline static thumbnail with a `GIF` badge; the selected GIF loops silently in place (Kitty graphics mode). Requires `ffmpeg` — see below.
- **Audio (music)** — performer / title / duration; other media types show a labelled placeholder.
**Sending media** — attach an existing file from disk with `u` (photos, videos,
voice notes, music, documents) and confirm the send-as type before sending.
> **Recording is out of scope.** `tele` can _send_ a pre-recorded audio or video
> file, but it cannot **record** voice messages or round videos (кружки) in-app:
> as a terminal-native, cgo-free client it has no microphone or camera capture
> stack. This is an architectural boundary, not a missing feature on the roadmap.
> **Optional dependency — `ffmpeg`:** install `ffmpeg` (with `ffprobe`) on your `PATH` to enable inline GIF playback (decoding frames) and to attach duration/dimensions/thumbnail metadata when sending videos. It is entirely optional: without it, GIFs stay static and videos still send (Telegram generates the preview server-side).
### 🧠 Terminal-native design
Built specifically for terminal workflows — not adapted from a GUI client.
### 🚀 Lightweight by design
Single static Go binary with fast startup and low memory usage.
### ⚙ Simple configuration
YAML-based config with sensible defaults.
---
## Installation
### macOS / Linux — Homebrew
```sh
brew tap sorokin-vladimir/tap
brew install tele
```
### Linux — binary
```sh
curl -sL https://github.com/sorokin-vladimir/tele/releases/latest/download/tele-linux-amd64 \
-o ~/.local/bin/tele && chmod +x ~/.local/bin/tele
```
For arm64: replace `amd64` with `arm64`.
### Windows — binary
Download the executable with PowerShell (run as your normal user):
```powershell
$dir = "$Env:LOCALAPPDATA\Programs\tele"
New-Item -ItemType Directory -Force -Path $dir | Out-Null
Invoke-WebRequest `
-Uri "https://github.com/sorokin-vladimir/tele/releases/latest/download/tele-windows-amd64.exe" `
-OutFile "$dir\tele.exe"
```
For arm64: replace `amd64` with `arm64`. Add `$dir` to your `PATH` (or run
`tele.exe` by full path), then launch it from a terminal that supports the Kitty
graphics protocol — e.g. [WezTerm](https://wezterm.org) — for inline images.
A plain console (cmd.exe / classic conhost) falls back to ANSI block-art photos.
> Prefer a packaged install? A `.zip` containing `tele.exe`
> (`tele_windows_amd64.zip`) is attached to every [release](https://github.com/sorokin-vladimir/tele/releases/latest).
---
## First launch
```sh
tele
```
On first run, `tele` creates:
```text
~/.config/tele/config.yml
```
Then prompts for:
- phone number
- SMS code
- optional 2FA password
---
## Flags
| Flag | Description |
| ----------------- | ---------------------------------------------------------------------------------------------- |
| `--config ` | Path to config file (default `~/.config/tele/config.yml`) |
| `-e` | Enable debug logging |
| `--trace` | Log sensitive metadata (peer IDs, message lengths). Never use on shared or synced file systems |
| `--version` | Print version and exit |
---
## Keybindings
| Key | Action |
| ------------------- | ----------------------------------------------- |
| `j` / `k` | Navigate chats or scroll messages |
| `ctrl+j` / `ctrl+k` | Select next / previous message |
| `i` | Compose message |
| `r` | Reply |
| `e` / `d` | Edit / delete message |
| `t` | React |
| `f` | Forward message |
| `u` | Attach a file to send |
| `o` | Open / view media (photo in viewer, video inline) |
| `O` | Open video in the external player |
| `p` | Play voice message in-app |
| `s` | Download the selected file |
| `/` | Search chats |
| `space` | Message context menu |
| `0` / `1` / `2` | Focus panes |
| `q` | Quit |
Full reference: [docs/keybindings.md](docs/keybindings.md)
---
## Configuration
```yaml
telegram:
session_file: ~/.config/tele/session.json
ui:
history_limit: 50 # messages fetched per chat on open
photos:
mode: auto # auto | kitty | blocks — inline image renderer
eager_full_quality: true # download full resolution in the background on chat open
kitty_placement_cap: 16 # max inline images kept on the terminal at once
max_long_side_px: 800 # cap a rendered image's long side; height also ≤ 2/3 pane
# keybindings: see "Customizing keybindings" below
```
> **`kitty_placement_cap`** bounds how many Kitty image placements are live on
> the terminal simultaneously. Only on-screen images (plus a few recently
> scrolled-past) are transmitted; older ones are evicted. Transmitting an entire
> heavy chat at once can exceed the terminal's image limit and corrupt
> placements (shrunken/shifted photos) — lower the cap if you still see that.
> **`max_long_side_px`** caps a rendered inline image's long side in pixels
> (mirrors the desktop clients' fixed media size). The height is additionally
> bounded to 2/3 of the chat pane so a tall photo never dominates the view.
> Raise it for larger inline images, lower it for more compact ones.
### Customizing keybindings
Override default keys in the `keybindings:` section of `~/.config/tele/config.yml`.
The generated config already lists **every action with its current default keys**,
commented out — just uncomment a line and change the key(s). Bindings are grouped
by **context**, then by **action**:
```yaml
keybindings:
chat:
reply: "R" # a single key
go_top: ["g g", "gg"] # several keys for one action
chatlist:
confirm: "l"
```
- **Replace semantics:** the keys you list become the _only_ keys for that
action in that context. Actions you don't mention keep their defaults.
- **Chords:** a multi-key sequence is written as space-separated key tokens —
`"g g"` means press `g` then `g`. Tokens use the terminal key names
(`ctrl+d`, `enter`, `esc`, `space`, `up`, ...).
- **Conflicts** (an unknown action/context, an empty key, a key reused for two
actions, or a single key that shadows a chord) are logged as warnings on
startup and skipped or applied last-wins; a bad section never crashes the app.
**Contexts:** `global`, `folders`, `chatlist`, `chat`, `composer`, `search`,
`context_menu`, `delete_submenu`, `chat_menu`, `folder_submenu`, `filepicker`.
See [docs/keybindings.md](docs/keybindings.md#configurable-actions) for the full
list of action names and what each one does.
---
## Roadmap
Planned work lives on the public [**project board**](https://github.com/users/sorokin-vladimir/projects/2),
grouped into release [milestones](https://github.com/sorokin-vladimir/tele/milestones).
| Release | Focus |
| --------- | ----------------------------------------------------------------------------------------------------------- |
| `v1.7.0` | Input & navigation polish — extended markdown, word-wise composer motions, mouse support, native Linux packages, search-to-create chats |
| `v1.8.0` | Notifications & messaging UX — toast banners, in-app alerts for inactive chats, `@mentions`, own-message alert suppression |
| `Backlog` | Power-user polish — themes, vim motions, command palette, full-text search |
Work is also categorized by theme (Security & Reliability, Architecture & Performance,
Feature Completeness, Power User & Polish) via the board's **Theme** field.
---
## Build from source
Requires Go 1.26+ and your own [Telegram API credentials](https://my.telegram.org).
```sh
git clone https://github.com/sorokin-vladimir/tele
cd tele
go build \
-ldflags "-X main.buildAPIID=YOUR_API_ID -X main.buildAPIHash=YOUR_API_HASH" \
-o tele ./cmd/tele/
```
---
## License
GPL-3.0 — free to use and fork; derivative works must remain open-source.
---
Built with:
- [gotd/td](https://github.com/gotd/td)
- [bubbletea](https://github.com/charmbracelet/bubbletea)
- [lipgloss](https://github.com/charmbracelet/lipgloss)
- inspired by [lazygit](https://github.com/jesseduffield/lazygit)