Skip to main content

Bor - Terminal Email Reader

Tests PyPI

Bor means pine in Slovenian. Bor is also an email reader inspired by pine.

I used to use pine and later its derivatives (alpine, realpine) until it became unsustainable. I switched to mu4e over a decade ago, but while I liked many things, it was never quite perfect.

A few years ago I switched away from emacs to VSCode and with the advent of AI coding I finally bite the bullet and made my very own mail client that works exactly the way I want it. Think of bor as pine dragged (by its feet) into 2025.

Bor uses mu for email access under the hoold and Textual for the user interface.

Some screenshots

Message index

alt text

Tabbed message reading

alt text

In-terminal preview using kitty terminal protocol

alt text

Features

  • Fast email searching using mu's powerful query language
  • Threaded message view with visual indentation
  • Message composition with address autocompletion and Ctrl-C/V/X handling global clipboard even in terminal
  • Attachment handling with preview (using kitty terminal graphics capabilities)
  • Keyboard-driven interface
  • Tab-based workflow
  • Configurable via TOML configuration file
  • HTML email support via html2text rendering

Requirements

  • Python 3.10+
  • mu (maildir indexer)
  • Textual library
  • Optional: html2text for HTML email rendering
  • Optional: kitty terminal for image preview

Known issues

  • no support for folders. You can mu search with maildir:/folder, but all archived messages go to the archived folder. This is how my work-flow works. Feel free to add and make pull request.
  • Clicking with mouse on the link does not work. For emails with one or two links, 'O' shortcut is preferrable, but for complex long messages, clicking on the link would be better.

Installation

From PyPI

pip install bormail

From source

# Clone the repository
git clone https://github.com/your-repo/bor.git
cd bor

# Install with pip
pip install -e .

# Or install dependencies manually
pip install textual tomli html2text

Dependencies

# Install mu on Debian/Ubuntu
sudo apt install maildir-utils

# Install mu on Arch Linux
sudo pacman -S mu

# Install mu on macOS
brew install mu

Release

  1. Update the version in pyproject.toml.
  2. Create a git tag like v0.1.1 and publish a GitHub Release.
  3. The Build workflow will upload the sdist and wheel to PyPI.
    • Configure PyPI Trusted Publishing for slosar/bor before the first release.

Configuration

Copy the example configuration file and customize it:

cp bor.conf.example ~/.config/bor.conf

Edit ~/.config/bor.conf to configure:

  • SMTP server settings
  • Maildir folder paths
  • Display preferences
  • Color scheme
  • Synchronization command
  • Email and text aliases

See the configuration documentation for details.

Usage

Start Bor:

python -m bor.app

Or if installed:

bor

Keyboard Shortcuts

Global

Key Action
Alt+0 Message Index tab
Alt+1-9 Switch to tab
Ctrl+Q Quit

Message Index

Key Action
↑/↓ or N/P Navigate messages
Enter Open message
R Reply
F Forward
C Compose new
S Search (mu query)
I Show Inbox
O Show Archive
U Show Drafts
M Mark message
X Archive message(s)
A Apply flag
D Delete message(s)
E Edit draft
T Toggle threading
Ctrl+T Show thread
L Sync
Z Undo move
Ctrl+R Refresh index

Message View

Key Action
Space/PgDn Scroll down
< Return to index (keep tab open)
Q Close tab and return
N/P Next/Previous message
R Reply
F Forward
C Compose new
M Mark/unmark message and advance
X Archive
D Delete
A Apply flag
O Open URL (if multiple, pick [1-9])
Z View attachments
Ctrl+R Toggle full headers

Compose

Key Action
Tab Autocomplete address/text
Ctrl+L L Send message
Ctrl+L D Save draft
Ctrl+L X Cancel
Ctrl+L A Attach file
Ctrl+L Z Attach many files from a directory
Ctrl+I Insert file

Ctrl+L A opens a file-path prompt with bash-like tab completion: one match completes immediately, multiple matches are listed without forcing a choice, and the input expands only to the longest shared prefix.

Ctrl+L Z first prompts for a directory with the same tab-completion behavior, then opens a file picker where Space marks files, Enter attaches the marked set, Esc cancels, and Ctrl+A toggles all.

Attachments

Key Action
1-9 Select attachment
Enter Open with system viewer
S Save attachment
Shift+S Save all
Q or Esc Close and return to message view
< Return to index (keep tab open)

URL opener limitation

The URL picker shows and opens the first 9 URLs. If a message has more than 9 URLs, it is easier to copy/paste the link or use terminal link clicking instead.

Search Queries

Bor uses mu's query language. Examples:

# Search in inbox
maildir:/INBOX

# Unread messages
flag:unread

# From a specific sender
from:john@example.com

# Subject contains word
subject:meeting

# Date range
date:1w..now

# Combine queries
from:john subject:meeting flag:unread

License

MIT. See LICENSE.

See the mu query documentation for more.

Development

Project Structure

bor/
├── __init__.py       # Package init
├── app.py            # Main Textual application
├── config.py         # Configuration handling
├── mu.py             # Mu interface
└── tabs/
    ├── __init__.py
    ├── base.py       # Base tab class
    ├── message_index.py
    ├── message.py
    ├── compose.py
    ├── attachments.py
    └── sync.py

Running tests

pytest tests/

License

MIT License - see LICENSE file for details.

Credits

  • mu/mu4e - Email indexing and searching
  • Textual - TUI framework
  • Inspired by traditional email clients like pine, mutt, and mu4e

Metadata

Release files for bormail 1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bormail 1.0
File Size Uploaded
bormail-1.0.tar.gz 96.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bormail 1.0
File Interpreter ABI Platform
bormail-1.0-py3-none-any.whl Python 3 none any Details

Total release size: 175.1 kB

Release files / bormail-1.0.tar.gz

Download URL bormail-1.0.tar.gz
Size 96.2 kB
Tags Source
SHA-256 checksum
How to use checksums
eac2e180b628e6d2ea3eab75ca5d4117e9e7bc05fe2008272d96b3974a53fc19
BLAKE2b-256 checksum
How to use checksums
215d2a92d261a22b902595652b4f10c5e2924e23363b23e18813fff415f1d02e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 24, 2026.

Transparency log

Release files / bormail-1.0-py3-none-any.whl

Download URL bormail-1.0-py3-none-any.whl
Size 78.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5269a3570ebe34fe13de6402278048aea7e27ab5f9844cabbd43b83a3af3f1a0
BLAKE2b-256 checksum
How to use checksums
198df78f215cafb9c397f98192101b059af3d0958dd9ceaf1f53a0d7f1e6b6c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0 This release

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page