Skip to content

Repository files navigation

TUI Email Client

A lightweight terminal-based email client with Outlook-like workflow and secure local storage. Interact with intuitive keyboard shortcuts. Use --headless to work through your inbox with Text To Speech for visually impaired users (voice operated mode planned).

If you need more features, you probably should just open a browser and go to your provider's webmail.

TL;DR: Simple-by-design email client for the terminal. Configure, then type f to Fetch the currently highlighted folder. Spacebar to view in a modal, c to Compose new message, R to Reply, r to mark as Read, W to forWard, t to listen (offline TTS), navigate with arrow keys.

Features

  • Folder view: Inbox, Sent, Drafts, Archive, Flagged, Spam, Trash
  • Conversation view inside each folder (threads grouped by subject)
  • Scrollable detail pane with wrapped message bodies
  • Scrollable full-message modal viewer
  • Safe terminal rendering for HTML-only emails
  • Message operations:
    • o: Open Settings modal (reconfigure IMAP/SMTP/basic options)
    • d: Delete selected conversation with remote verification and immediate refresh
    • r: Toggle Read/Unread for selected conversation
    • s: Send selected draft (from Drafts)
    • R: Reply to selected message (opens prefilled compose)
    • W: Forward selected message (opens prefilled compose)
    • f: Refresh current folder from server
    • F: Refresh all folders from server
    • c: Compose new message (opens compose modal)
      • In compose modal: To, Cc, Bcc, Subject, Body fields
      • Tab/Shift+Tab switch fields, arrow keys move cursor, F2 saves draft, F10/Esc/q cancel
    • Space: Open selected email in scrollable modal viewer
      • In message modal: r reply, a reply all, f forward, t listen (offline TTS)
      • Up/Down, PgUp/PgDn, Home/End, and mouse wheel scroll
    • In Settings modal: F2 saves config, F5 resets (deletes local DB + config, then re-setup)
    • Sending with s shows a confirmation dialog (y/n) before sending
    • q: Quit
    • arrow keys / hjkl for navigation
    • [ / ] and PgUp / PgDn scroll the side detail pane
  • SQLite persistence for messages in ~/.tui_email/messages.db (or %APPDATA%\tui_email\messages.db on Windows)
  • Config stored in ~/.tui_email/config.json (or %APPDATA%\tui_email\config.json on Windows)

Initial setup

On first run, the client will prompt for:

  • IMAP host/port/ssl/username/password

For sending drafts with s, SMTP defaults are inferred from IMAP settings. You can add optional overrides in ~/.tui_email/config.json:

  • smtp_host
  • smtp_port (default 587)
  • smtp_ssl (default false)
  • smtp_starttls (default true when smtp_ssl is false)
  • smtp_user / smtp_pass (default to IMAP credentials)
  • fetch_limit (default 30)

This is a one-time setup. The config is written to ~/.tui_email/config.json.

How to run

cd ~/Projects/tuiemail
python3 tui_email.py

Build a distributable binary

This project can be distributed as a standalone console binary for Linux and Windows with PyInstaller.

Linux build

Install build dependency:

cd ~/Projects/tuiemail
./.venv/bin/python -m pip install -r requirements-build.txt

Build with the included spec:

./.venv/bin/python -m PyInstaller --clean tuiemail.spec

Or use the helper script:

sh build-pyinstaller.sh

Or use Make targets:

make release
make linux-release
make install

make install builds and installs the binary to /usr/local/bin/tuiemail by default. If needed, run with sudo for permissions, or set a custom prefix (for example, make install PREFIX=$HOME/.local).

The generated binary is written to:

dist/tuiemail

Windows build

From PowerShell/cmd:

cd C:\Users\LucasBurlingham\tuiemail
py -m pip install -r requirements-build.txt
py -m pip install windows-curses
py -m PyInstaller --clean tuiemail.spec

Or use Make targets (Git Bash / WSL make is required):

make release
make win-release

windows-curses is required for Windows. make win-release installs it automatically in the venv first.

The generated binary is written to:

dist\tuiemail.exe

Notes:

  • Windows builds may require adding C:\Users\<you>\AppData\Local\Python\pythoncore-<version>-64\Scripts to PATH so PyInstaller is found.
  • pyinstaller may warn about script location; ensure py does not conflict with existing Python installs.
  • Linux or Windows builds still use ~/.tui_email/config.json (or %APPDATA%\tui_email\config.json) and local message DB at runtime.

Notes:

  • Build on Linux for Linux distribution.
  • The binary still uses ~/.tui_email/config.json and ~/.tui_email/messages.db at runtime.
  • curses is a system capability on Linux, so build and test on a target-like environment.
  • A GitHub Actions workflow is included at .github/workflows/release.yml to build and upload a Linux binary for version tags like v1.0.0.

Storage and security

  • ~/.tui_email/config.json stores IMAP connection info (host/port/SSL/user/pass).
  • ~/.tui_email/messages.db is plain SQLite, used directly by the app.
  • The implementation currently does not encrypt message contents or the database on disk.

Data flow

  • App loads messages from database on startup (load_messages).
  • Folders are loaded from DB (load_folders) and the UI starts from cached local state.
  • UI is shown immediately using cached data from DB.
  • f refreshes the current folder from IMAP.
  • F refreshes all folders from IMAP, then reconciles local data with server state.
  • Read/unread/delete actions are persisted to DB immediately via save_message.
  • Delete now attempts remote removal, auto-refreshes the source folder, and reports verified server outcome in the status line.
  • Multipart messages prefer text/plain; HTML-only messages are converted to terminal-safe text.

Offline TTS support

The client supports offline text-to-speech for the currently selected message with:

  • t in the main view (for selected conversation latest message)
  • t in the message modal

Supported engines (auto-detected, preferred order):

  • piper (preferred; CLI must be installed and a voice model configured)
  • espeak
  • pico2wave + aplay
  • say (macOS fallback)

If no engine is present, the status line shows a warning.

Piper voice setup

On Windows/macOS, install the piper CLI or use the fallback PowerShell voice path.

The app downloads a default model to ~/.tui_email/piper_voices (or %APPDATA%\tui_email\piper_voices on Windows) if missing:

  • en_US-lessac-medium.onnx
  • en_US-lessac-medium.onnx.json

from:

To override existing paths, set config section in ~/.tui_email/config.json:

{
  "piper": {
    "voice": "en_US-lessac-medium",
    "model_path": "/path/to/en_US-lessac-medium.onnx",
    "config_path": "/path/to/en_US-lessac-medium.onnx.json"
  }
}

Also from the Settings modal, use the piper_voice dropdown to pick a voice ID (one of the voices listed in voices.json) and optionally specify piper_model_path and piper_config_path.

Dependencies

  • Python 3.8+
  • curses (std lib; on Linux built-in)
  • piper (recommended for best quality, optionally install from github.com/rhasspy/piper)

Troubleshooting

  • Ensure terminal is at least 80x24.
  • Ensure IMAP credentials are correct and reachable.
  • If folder sync fails, check network and server settings.
  • If delete reports messages still on server, verify that the remote mailbox supports the IMAP delete/expunge flow used by the account.
  • If mouse wheel scrolling does not work, confirm your terminal forwards mouse events to curses applications.

About

Simple TUI curses email client with TTS

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages