Feedr is a feature-rich terminal-based RSS feed reader written in Rust. It provides a clean, intuitive TUI interface for managing and reading RSS feeds with elegant visuals and smooth keyboard navigation.


tmlShift+F, or auto-extract on refresh per feed with fulltext = true? for a scrollable keybinding reference overlayfeedr --import <file.opml>j/k alongside arrow keys for navigationAuthorization: Bearer ...) for private/authenticated RSS feedsalways/never override in configfeedr config), or use the interactive TUI config editor (feedr config --tui)[keybindings] section in config.tomlpipe-to, exec) bound to keys, plus exec_on_new notifications fired per new item — all with shell-free argument templatingcargo install feedr
Feedr is available on the AUR. Install it using your preferred AUR helper:
paru -S feedr
# or
yay -S feedr
git clone https://github.com/bahdotsh/feedr.git
cd feedr
cargo build --release
The binary will be available at target/release/feedr.
Run the application:
feedr
Import feeds from an OPML file:
feedr --import feeds.opml
View and modify settings from the command line:
feedr config list # List all settings with current values
feedr config get ui.theme # Get a single value
feedr config set ui.theme light # Set a value (with validation)
feedr config --tui # Open interactive TUI config editor
Available config keys use dot-notation (e.g. general.max_dashboard_items, network.http_timeout, ui.theme, ui.compact_mode). Run feedr config list to see all keys. Feed management (default_feeds) is only available through the TUI editor.
a to add a feedhttps://news.ycombinator.com/rss)1, 2, or 3 to quickly add Hacker News, TechCrunch, or BBC Newsj/k) to navigate and Enter to view itemso to open the current article in your browsert to toggle between dark and light themesAll keybindings below show their defaults. You can remap any action via the [keybindings] section in your config file — see Configurable Keybindings.
| Key | Action |
|---|---|
Tab |
Cycle forward through views |
Shift+Tab |
Cycle backward through views |
q |
Go back (quit from Dashboard) |
h / Esc / Backspace |
Go back one view |
Home |
Return to Dashboard |
Ctrl+Q |
Quit from any view |
r |
Refresh all feeds |
t |
Toggle dark/light theme |
/ |
Search mode |
? |
Help overlay (scrollable keybinding reference) |
| Key | Action |
|---|---|
↑/↓ or k/j |
Navigate items |
g / G or End |
Jump to top / bottom |
Enter |
View selected item |
f |
Filter articles |
c |
Cycle category filter |
Ctrl+C |
Open category management |
a |
Add a new feed |
s |
Toggle starred |
Space |
Toggle read/unread |
m |
Mark all items as read |
p |
Toggle preview pane |
Shift+J / Shift+K |
Scroll preview down / up |
o |
Open link in browser |
1/2/3 |
Quick-add demo feeds (HN, TechCrunch, BBC) |
| Key | Action |
|---|---|
q / h / Esc |
Go to dashboard |
↑/↓ or k/j |
Navigate feeds |
Enter |
View feed items |
Space |
Expand/collapse category (tree view) |
a |
Add a new feed |
d |
Delete selected feed |
c |
Assign category to feed |
| Key | Action |
|---|---|
q / h / Esc / Backspace |
Back to feeds list |
Home |
Go to dashboard |
↑/↓ or k/j |
Navigate items |
g / G or End |
Jump to top / bottom |
Enter |
View item details |
s |
Toggle starred |
Space |
Toggle read/unread |
m |
Mark all items as read |
o |
Open item in browser |
| Key | Action |
|---|---|
q / h / Esc / Backspace |
Back to feed items |
↑/↓ or k/j |
Scroll content |
Ctrl+U / Ctrl+D |
Scroll content (page) |
Page Up / Page Down |
Scroll content (page) |
g |
Jump to top |
G / End |
Jump to bottom |
s |
Toggle starred |
o |
Open item in browser |
l |
Extract and show all links |
Shift+F |
Toggle/fetch full-text (Readability) |
| Key | Action |
|---|---|
↑/↓ or k/j |
Navigate items |
Enter |
View item details |
s |
Remove from starred |
o |
Open item in browser |
| Key | Action |
|---|---|
n |
Create new category |
e |
Rename category |
d |
Delete category |
Space |
Expand/collapse category |
Enter |
Select category |
r |
Refresh |
? |
Help |
h / Esc / q |
Back |
f on Dashboard)| Key | Action |
|---|---|
c |
Filter by category |
t |
Filter by time/age |
a |
Filter by author |
r |
Filter by read status |
s |
Filter by starred status |
l |
Filter by content length |
x |
Clear all filters |
| Action | Effect |
|---|---|
| Left click | Select item |
| Scroll up/down | Navigate items |
Feedr supports customization through a TOML configuration file that follows XDG Base Directory specifications. You can edit the file directly, use feedr config get/set from the command line, or use feedr config --tui for an interactive editor.
~/.config/feedr/config.toml%APPDATA%\feedr\config.tomlThe configuration file is automatically generated with default values on first run if it doesn't exist.
# Feedr Configuration File
[general]
max_dashboard_items = 100 # Maximum number of items shown on dashboard
auto_refresh_interval = 0 # Auto-refresh interval in seconds (0 = disabled)
refresh_enabled = false # Enable automatic background refresh
refresh_rate_limit_delay = 2000 # Delay in milliseconds between requests to same domain
[network]
http_timeout = 15 # HTTP request timeout in seconds
user_agent = "Mozilla/5.0 (compatible; Feedr/1.0; +https://github.com/bahdotsh/feedr)"
[ui]
tick_rate = 100 # UI update rate in milliseconds
error_display_timeout = 3000 # Error message duration in milliseconds
theme = "dark" # Theme: "dark" (cyberpunk) or "light" (zen)
compact_mode = "auto" # Compact layout: "auto", "always", or "never"
# Optional: Define default feeds to load on first run
[[default_feeds]]
url = "https://example.com/feed.xml"
category = "News"
# Authenticated feed with custom HTTP headers
[[default_feeds]]
url = "https://private.example.com/feed.xml"
[default_feeds.headers]
Authorization = "Bearer your_token_here"
"dark" (cyberpunk aesthetic with neon colors) or "light" (zen minimalist with organic colors). Can also be toggled at runtime with t."auto" (default) enables compact mode when terminal height is ≤30 rows, "always" forces compact mode, and "never" disables it. Compact mode uses single-line items, a minimal title bar, and an abbreviated help bar to maximize screen real estate.To enable automatic refresh every 5 minutes with rate limiting:
[general]
refresh_enabled = true
auto_refresh_interval = 300 # 5 minutes
refresh_rate_limit_delay = 2000 # 2 seconds between requests to same domain
Note: Rate limiting groups feeds by domain and staggers requests to prevent hitting API limits. For example, if you have multiple Reddit feeds, they will be fetched with a 2-second delay between each request to avoid getting blocked.
You can define feeds to be automatically loaded on first run:
[[default_feeds]]
url = "https://news.ycombinator.com/rss"
category = "Tech"
[[default_feeds]]
url = "https://example.com/feed.xml"
category = "News"
# Optional per-feed refresh threshold (seconds). When this elapses since
# the last refresh, the next auto-refresh tick is triggered — currently
# all feeds are refreshed together (no true selective per-feed refresh).
# Requires `general.refresh_enabled = true`.
[[default_feeds]]
url = "https://example.com/fast-feed.xml"
refresh_interval = 60
Some RSS feeds require authentication or custom HTTP headers. You can configure per-feed headers:
[[default_feeds]]
url = "https://private.example.com/feed.xml"
[default_feeds.headers]
Authorization = "Bearer your_api_token"
[[default_feeds]]
url = "https://another-api.example.com/rss"
[default_feeds.headers]
X-API-Key = "your_api_key"
Cookie = "session=abc123"
Headers are sent with every request for that feed, including refreshes.
Most RSS feeds ship only short summaries. Feedr can fetch the linked article URL and run Mozilla Readability (via the dom_smoothie crate) to extract the actual article body and render it inline.
Shift+F to extract the focused article. Press Shift+F again to toggle back to the original summary, or after a failure to retry.fulltext = true on a feed and Feedr will auto-extract newly-seen items on each refresh (same "no firehose" rule as exec_on_new — the first observation of a feed seeds silently).[[default_feeds]]
url = "https://example.com/summary-only-feed.xml"
fulltext = true
Notes:
- Extracted content is in-memory only — it is not persisted to disk. A restart re-extracts on demand.
- Per-feed auth headers are not sent to the article URL (article URLs are typically third-party hosts; forwarding Authorization would leak cred
$ claude mcp add feedr \
-- python -m otcore.mcp_server <graph>