> termcourse: read & post on Discourse instances from the terminal

This is a Terminal App (TUI), just a bit of fun … and a bit experimental at this stage!

:information_source: Summary A terminal UI for browsing and posting to Discourse forums with topic lists, full topic views, replies, likes, search, and a built‑in composer.
:hammer_and_wrench: Repository Link GitHub - merefield/termcourse: A terminal based client to access Discourse instances, supporting API keys, username/password (and with MFA token) · GitHub
:open_book: Install Guide README.md in the repo (Quickstart section)
:heart: Sponsorship Please consider becoming an ongoing sponsor of my open source work (Sponsor @merefield on GitHub Sponsors · GitHub) at a level that suits your or your organisation’s resources and needs to ensure this project gets the maintenance it deserves and continues to work for your site in the future.

Enjoying termcourse? Please :star: it on GitHub

Overview

termcourse is a terminal-based Discourse client, rebuilt as a single Go executable. It can use a lightweight browser-style cookie session with username/email and password, including TOTP and backup-code MFA. API-key authentication is available for sites where interactive login is unsuitable.

The interface uses the current Charm stack and works with both keyboard and mouse. Its folder-style navigation, contextual filters, responsive panels, themed controls, Markdown rendering and inline images are designed to make browsing a forum comfortable without leaving the terminal.

Features

  • Browse Latest, Hot, New, Unread, Top and Private Message topic lists, with Top period cycling.
  • Navigate persistent Topics, Search, Notifications and Compose folders, with contextual second-level filters.
  • Use the keyboard throughout, or click tabs, topic rows, footer controls and hover-highlighted buttons.
  • Open visible topics with Enter or number keys 10.
  • Read complete topics with lazy post loading, compact excerpts, expanded selected posts and responsive scrolling.
  • Click a topic’s progress track to jump directly to that point in the post stream.
  • Create topics, choose categories, reply to topics or individual posts, and like or unlike posts.
  • Search posts and jump directly to the matching post in its topic context.
  • Browse and filter notifications, including unread and private-message badges.
  • Compose multiline content with cursor movement, insertion, wrapping, paste support and live validation.
  • Render GFM Markdown including links, lists, quotes, code, task lists and tables.
  • Show high-quality inline and fullscreen images with the Kitty graphics protocol, with colored chafa symbols or viu as portable fallbacks.
  • Receive realtime topic-list, topic, notification and private-message updates when using a cookie session.
  • Use per-site credentials from the environment or credentials.yml, with prompting for missing login fields.
  • Choose from default, slate, fairground, rust and hacker themes, add YAML themes, and cycle themes while the app is running.
  • Use truecolor, 256-color or 16-color output with automatic terminal capability detection.
  • Run the interface in English, French, German or Spanish.
  • Resize the terminal freely: layouts, colours, topic lists and Kitty images respond to the available space.
  • See server-provided retry timing when Discourse rate limits an action, with optional HTTP, UI and image diagnostics.

Install and run

On Linux or macOS, the recommended installer downloads the prebuilt release for the current operating system and architecture, verifies its SHA-256 checksum and reported version, then installs it:

curl -fsSL https://raw.githubusercontent.com/merefield/termcourse/master/install-release.sh | sh
termcourse your.discourse.host

Termcourse prompts for a username and password when credentials have not already been configured. Password input is hidden.

Use termcourse --version to show the installed semantic version; the same version appears in the wide terminal masthead.

For a user-local installation that does not require sudo:

curl -fsSL https://raw.githubusercontent.com/merefield/termcourse/master/install-release.sh |
  TERMCOURSE_BIN_DIR="$HOME/.local/bin" sh

Each GitHub Release provides SHA-256 checksums and prebuilt archives for Linux, macOS and Windows on AMD64 and ARM64. Linux/macOS use .tar.gz; Windows uses .zip. Prebuilt releases do not require Go.

On Windows, download and inspect the installer, then run it without changing the machine-wide execution policy:

Invoke-WebRequest https://raw.githubusercontent.com/merefield/termcourse/master/install-release.ps1 -OutFile install-release.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File .\install-release.ps1

It installs to %LOCALAPPDATA%\Programs\termcourse\bin by default and performs the same checksum and version verification. The installers can also pin a release with --version or -Version. Go 1.26.6 or newer is only required when installing from source.

To build a local executable from a checkout instead:

git clone https://github.com/merefield/termcourse.git
cd termcourse
make build
./termcourse your.discourse.host

For repeat use, put login details in a local .env or use the per-host credentials.yml described in the README.

Username/password login (recommended)

Username/password login enables realtime updates:

DISCOURSE_USERNAME="you@example.com" \
DISCOURSE_PASSWORD="your_password" \
termcourse your.discourse.host

API-key fallback

DISCOURSE_API_KEY="your_key" \
DISCOURSE_API_USERNAME="your_username" \
termcourse your.discourse.host

See the latest README for configuration, themes, controls, image backends and troubleshooting.

Authentication notes

  • Username/password login follows Discourse’s CSRF and cookie flow and enables realtime MessageBus updates.
  • TOTP and backup-code MFA are supported.
  • API-key authentication retains HTTP functionality but does not establish a realtime browser session.
  • Some sites disable or restrict scripted username/password login; API credentials are the fallback for those sites.

Security

  • Termcourse does not write prompted credentials or session cookies to disk; session cookies remain in memory.
  • Password prompting keeps the password out of shell history.
  • Persistent credentials are optional and remain under the user’s control in environment or YAML files.
  • Diagnostic logging is opt-in, disabled by default, and does not log credentials or response bodies.

Limitations

  • Sites that forbid remote login flows may require API-key authentication.
  • Realtime updates require username/password cookie authentication.
  • Native inline image quality depends on terminal support; Kitty is preferred, with symbol rendering available elsewhere.
  • It lives in the terminal. :slight_smile:

Credits

Partly inspired by Dumbcourse: old browser friendly UI at dumb/d-pad/small screens. :clap:

27 Likes

So you can quickly login to multiple sites (obviously one session at a time per tab) I’ve made the following improvements:

termcourse auth and config improvements

  • Username/password is now the default login path.
  • You don’t need to include https:// anymore - this is optional
  • Missing login fields are prompted interactively (for example: username known, password missing).
  • CLI help includes core env vars and debug log file locations.

Credentials and ENV behavior

  • Supports host-mapped credentials file with lookup order:
    1. TERMCOURSE_CREDENTIALS_FILE (if set)
    2. ./credentials.yml
    3. ~/.config/termcourse/credentials.yml
  • Auth precedence:
    1. CLI flags
    2. Host credentials from YAML
    3. Generic DISCOURSE_* env vars
    4. Interactive prompt
  • For auth: login, missing username/password values are prompted.
  • For API auth, both API username and key must resolve to non-empty values.

Debugging

  • HTTP/auth debug: TERMCOURSE_HTTP_DEBUG=1 → /tmp/termcourse_http_debug.txt
  • UI render debug: TERMCOURSE_DEBUG=1 → /tmp/termcourse_debug.txt

Repo hygiene

  • Added credentials.example.yml and .env.example with aligned examples.
  • Added .gitignore entries for local secret files:
    • .env
    • credentials.yml
3 Likes

This is pretty low-fi but it works.

You need to have viu or chafa installed - and that can be a project itself :slight_smile:

In high quality mode on chafa or with viu, Windows Terminal is superior to MacOS terminal because it supports many more colours (thanks Microsoft!)

Release Notes: Image Rendering (in the terminal!)

Image Rendering

  • Added inline post image previews with backend selection:
    • auto tries chafa first, then viu.
    • TERMCOURSE_CHAFA_MODE=stable|quality
    • stable: conservative output for terminal stability.
    • quality: higher-detail/color symbol rendering.
  • Added preview height control:
    • TERMCOURSE_IMAGE_LINES (default: 14)
    • Applies to preview line height; useful for tuning visual density.
  • Improved viu aspect behavior:
    • Switched to line-targeted rendering (-h) to preserve aspect ratio better.
  • Added preview quality filter controls:
    • TERMCOURSE_IMAGE_QUALITY_FILTER=1 filters noisy block-only previews.
    • Set to 0 to always show renderer output.
  • Added image download safety limit:
    • TERMCOURSE_IMAGE_MAX_BYTES (default: 5242880)
    • Prevents oversized image downloads from impacting performance.
  • Added support for Discourse upload://… image links:
    • Automatically resolves to /uploads/short-url/…
  • Improved terminal sanitization/stability:
    • Keeps valid SGR color codes where needed.
    • Strips destabilizing control/graphics sequences.
    • Prevents ANSI escape fragments from being displayed as raw text.

A note: I’ve found one site that blocks remote username/password so this client will not work in that situation (unless you own it and can set an API key!)- suggestions welcome, but currently no support in those instances.

I’m not sure I’ll use this in the real world, I don’t see the use for me, but I’ve tried it and it’s delightful. I love being able to interact with a next-gen forum platform from a bare-metal, primitive interface.

In some way, it is very aesthetically pleasing.

1 Like

Thank you!

Yeah, I’m thinking it might be useful when:

  • you are on a low fi platform
  • mucking around on a raspberry pi (not yet tested FYI)
  • from a server to check you are up …
  • … or if the front end code is crashing! :smiley:
  • for a Discourse site that is very text based …
  • … and as a technical curiosity :nerd_face:

I’ve been meaning to test it on my phone with Terminus …

3 Likes

OK probably last update for today:

  • interface is now responsive to window resize :tada:
  • improvements to content in top bar instructions
  • keys 1 to (1)0 now open that number topic on the topic list

Remember to git pull to get updates.

3 Likes

Man, now I gotta get to work on my ASCII artwork!!
¯(ツ)

3 Likes

I’ve added a fully customisable theming system, this is “fairground”:

… and this is “slate”:

… and this is “rust”:

details in the README :graduation_cap:

5 Likes

ok here we go guys, some juicy :tangerine: updates:

  • add support for Private Messages - tap f twice :tada: (just list, view and reply at this stage no compose new PM)
  • add additional columns for Category, Users, Views, progressively when width expanded
  • tweak theming for vertical separators
  • updated README

2 Likes

I merged this yesterday:

  • If you make the effort to install chafa or viu, you will now be rewarded with a new feature: “full window” toggle for post images. On Windows this is particularly good because of the generous colour depth support in Windows Terminal app

termcourse now has an unread PM status pop-up in the topic list status bar and just like the browser client will post back read notifications post by post as you move the cursor

2 Likes

I’ve merged fixes for themes on macos

2 Likes

Nice… Does it run on a Pip-Boy?

3 Likes

feel free to PR that or share the colour codes and I’ll add to the example themes yml :slight_smile:

2 Likes

Love it! Merged, thank you!

https://github.com/merefield/termcourse/pull/1

2 Likes

https://github.com/merefield/termcourse/pull/2

So the rendering wasn’t great … so I’ve fixed it … the UI now has “diff rendering” so it’s much faster and smoother … it no longer paints the whole screen with every cursor movement. :sweat_smile:

I’ve only tested this under windows so far so please feed back any issues - but it should help slower systems significantly.

I’ve also added some tests and GitHub CI! (and it’s super fast because it uses minitest)

Now has a realtime notification system based on MessageBus to notify you in status bar when the topic list has new updates (so you can hit g to refresh):

https://github.com/merefield/termcourse/pull/3

Will probably work on topic read badges next …

That’s great!

Why not use the same keyboard shortcuts as Discourse? So the experience would be more seamless :slight_smile:

1 Like

Not a bad idea … that’s definitely worth a pass at some stage to see if things can be sensibly brought closer together :+1: … but there are of course some significant differences in medium so some things might remain different.

1 Like