PodcastTUI lqdev
winget install --id=lqdev.PodcastTUI -e A Terminal User Interface for Podcast Management
winget install --id=lqdev.PodcastTUI -e A Terminal User Interface for Podcast Management
A cross-platform terminal user interface for podcast management built with Rust.
> 📚 Documentation: For comprehensive architecture and design patterns, see ARCHITECTURE.md
v1.12.0 — The application has a fully working feature set for podcast subscription management, downloading, device sync, playlist management, audio playback, discovery, tagging, and optional scrobbling.
✅ Working Features:
Today auto-playlist, smart playlists):clean-older-than):discover, :trending)*), mark played (m) / unplayed (u), podcast taggingextends⏳ Not Yet Implemented:
⚠️ Episode notes and statistics tracking are not yet implemented. The current release is suitable for managing subscriptions, downloading episodes, playing audio, syncing to devices, managing playlists, and discovering new podcasts.
✅ Completed Features:
Today (last 24h) playlist, and smart playlists:discover, :trending):tag, :untag, :filter-tag)*), mark played/unplayed (m/u)⏳ In Progress / Planned:
Podcast TUI exposes three customization surfaces in config.json. See docs/KEYBINDINGS.md and docs/DEVICE_PROFILES.md for the full reference.
ui.startup_buffer to one of help, podcast-list, downloads, sync, playlist-list, whats-new, now-playing to control which buffer opens on launch. Default: help.keybindings.preset to default, vim, or emacs. Per-action overrides go under keybindings.bindings.device_profiles[] with a filename_template and select it via active_device_profile. The local downloads directory is untouched; only the device-side filenames are rewritten during sync. The :set-device-profile minibuffer command switches profiles at runtime.The storage layer also caches all podcasts, episodes, and playlists in memory and persists the index to cache_index.json, making warm launches near-instant. Toggle with storage.cache_enabled (default true); rebuild with :cache-rebuild. See docs/STORAGE_DESIGN.md for benchmark numbers.
> 📖 Documentation: > - 📚 Complete guide: GETTING_STARTED.md - Detailed platform-specific instructions and quick start > - 🏗️ Architecture: ARCHITECTURE.md - System design and technical documentation
⚠️ Important Build Notes:
The application is currently in active development with core RSS/download features and audio playback complete.
🚧 Development Status: Pre-built binaries are available for testing core features (RSS subscriptions, downloads, audio playback, and UI).
winget install lqdev.PodcastTUI
# Try it (zero commitment)
nix run github:lqdev/podcast-tui
# Install to profile
nix profile install github:lqdev/podcast-tui
# Or add to your NixOS configuration (flake-based):
# inputs.podcast-tui.url = "github:lqdev/podcast-tui";
# environment.systemPackages = [ podcast-tui.packages.${system}.default ];
> 📖 See docs/NIX_PACKAGING.md for declarative config, Home Manager, development shell, and more.
Download the latest release for your platform from the releases page.
Windows (manual):
# Download and extract podcast-tui-vX.X.X-windows-x86_64.zip
# Run podcast-tui.exe
Linux:
# Download and extract podcast-tui-vX.X.X-linux-x86_64.tar.gz
tar -xzf podcast-tui-vX.X.X-linux-x86_64.tar.gz
cd podcast-tui-vX.X.X-linux-x86_64
./podcast-tui
git clone https://github.com/lqdev/podcast-tui.git
cd podcast-tui
cargo build --release
./target/release/podcast-tui
# Optional: Install icon and desktop entry on Linux
./scripts/install-icon-linux.sh
Linux/macOS:
# Install build dependencies (one-time setup)
./scripts/install-build-deps.sh
# Quick local build
./scripts/build-linux.sh
Windows:
# Verify dependencies
.\scripts\install-build-deps.ps1
# Quick local build
.\scripts\build-windows.ps1
See BUILD_SYSTEM.md for detailed build documentation and cross-platform build instructions.
cargo run to start the applicationPodcast TUI features a custom icon combining a cassette tape and RSS feed symbol, representing the audio content and subscription management capabilities.
Linux: After installing from a release package, run the included install-icon-linux.sh script to add the application icon to your system's application menu and file manager.
Windows: The icon is automatically embedded in the executable and will appear in the taskbar, Task Manager, and file explorer.
See assets/README.md for more details about the icon design and installation.
podcast-tuia to add your first podcasthttps://feeds.simplecast.com/54nAGcIl)D to download episodes, F1 or ? for helpShift+Enter on a downloaded episode to play it↑ / ↓ - Move up/down← / → - Move left/rightPage Up / Page Down - Scroll by pageHome / End - Jump to top/bottomEnter - Select/activate itemSpace - Select/activate itemTab - Next bufferShift+Tab - Previous bufferCtrl+Page Up - Previous buffer (alternative)Ctrl+Page Down - Next buffer (alternative)a - Add new podcast subscriptiond - Delete selected podcastr - Refresh selected podcast feedShift+R - Refresh all podcast feedsCtrl+r - Hard refresh (re-parse all episodes)Enter - Open episode detail / navigate into playlistShift+D - Download episode (works in episode list and episode detail)Shift+X or X - Delete downloaded file for selected episodep - Add selected episode to a playlist* - Toggle episode as favoritem - Mark episode as playedu - Mark episode as unplayedCtrl+x - Delete ALL downloaded episodes and clean up:clean-older-than - Delete downloads older than duration (e.g., 7d, 2w, 1m):cleanup - Alias for clean-older-than:playlists - Open playlist buffer:playlist-create [name] - Create playlist:playlist-delete - Delete playlist:playlist-refresh - Refresh Today auto-playlist:playlist-sync - Sync podcasts + playlists to device:smart-playlist - Create a smart playlist with auto-generated rules (⚡ prefix):discover - Search for new podcasts via PodcastIndex API:trending - Browse trending podcasts:tag - Add a tag to the selected podcast:untag - Remove a tag from the selected podcast:filter-tag - Filter podcast list by tag:theme - Switch theme
dark, light, high-contrast, solarizedcatppuccin-mocha, dracula, nord, gruvbox-dark, tokyo-night~/.config/podcast-tui/themes/.tomlF2 - Switch to podcast listF3 - Search (same as /)F4 - Switch to downloadsF5 - Refresh current bufferF6 - Clear all active filtersF7 - Switch to playlistsF8 - Switch to sync bufferF9 - Open NowPlaying bufferCtrl+b - Show buffer list / Switch bufferCtrl+k - Close current bufferCtrl+l - List all buffers/ or F3 - Open search (filter by text, matches title + description):filter-status - Filter by status:filter-date - Filter by date range:filter-tag - Filter podcasts by tag:clear-filters or F6 - Clear all active filtersF1 - Show helph or ? - Show help: - Command promptEsc - Cancel/hide minibufferq - Quit applicationF10 - Quit applicationShift+P - Toggle play/pauseShift+Enter - Play selected downloaded episodeCtrl+Left - Seek backward 10sCtrl+Right - Seek forward 10s+ / = - Volume up- - Volume downF9 - Open now playing bufferSee complete keybinding reference for all shortcuts.
Configuration is stored in JSON format at:
~/.config/podcast-tui/config.json%APPDATA%/podcast-tui/config.json{
"downloads": {
"directory": "~/Downloads/Podcasts",
"concurrent_downloads": 3,
"cleanup_after_days": 30,
"sync_device_path": "/mnt/mp3player",
"sync_delete_orphans": true,
"sync_preserve_structure": true,
"sync_dry_run": false,
"sync_include_playlists": true,
"use_readable_folders": true,
"embed_id3_metadata": true,
"assign_track_numbers": true,
"download_artwork": true,
"include_episode_numbers": true,
"include_dates": false,
"max_filename_length": 150
},
"playlist": {
"today_refresh_policy": "daily",
"auto_download_on_add": true,
"download_retries": 3
},
"audio": {
"volume": 0.8,
"seek_seconds": 10,
"external_player": null,
"auto_play_next": false,
"remember_position": true
},
"ui": {
"theme": "dark",
"show_progress_bar": true,
"whats_new_episode_limit": 50
},
"discovery": {
"podcastindex_api_key": "",
"podcastindex_api_secret": "",
"max_results": 20
},
"scrobbling": {
"enabled": false,
"server_url": "https://api.listenbrainz.org",
"token": ""
}
}
The device sync feature allows you to sync downloaded episodes and playlists to external MP3 players or USB devices via the interactive Sync buffer (F8):
sync_device_path: Default path to your device (can be overridden at runtime via p in the Sync buffer)sync_delete_orphans: Remove files on device that aren't on PC (default: true)sync_preserve_structure: Keep podcast folder structure on device (default: true)sync_dry_run: Preview changes without applying them (default: false)sync_include_playlists: Include playlists in sync (default: true)Usage (via Sync buffer — F8):
Press F8 to open the Sync buffer, then:
s - Start sync to configured device pathd - Run a dry-run preview (shows what would change)p - Open directory picker to choose a different target pathThe Sync buffer shows live progress during sync and a history of past sync operations.
Podcast TUI uses JSON files for data storage:
~/.local/share/podcast-tui/
├── config.json # Application configuration
├── podcasts/ # Podcast subscriptions
│ ├── {podcast-id}.json
├── episodes/ # Episode metadata and notes
│ ├── {podcast-id}/
│ │ ├── {episode-id}.json
├── playlists/ # Playlists metadata + audio copies
│ ├── Morning Commute/
│ │ ├── playlist.json
│ │ └── audio/
│ │ ├── 001-episode.mp3
│ ├── Today/
│ │ ├── playlist.json
│ │ └── audio/
└── themes/ # Optional user TOML theme files
└── my-theme.toml
This design allows for:
The application follows a modular architecture with clear separation of concerns:
See ARCHITECTURE.md for comprehensive technical documentation including:
We welcome contributions! Please see CONTRIBUTING.md for:
extends:clean-older-thanNot Yet Implemented:
Build Requirements:
libasound2-dev and pkg-configCurrent Limitations:
See GitHub Issues for current bugs and feature requests.
Licensed under the MIT License. See LICENSE for details.
Status: 🚀 Active Development (v1.12.0)
Maintainer: @lqdev
Version: 1.12.0
Today:smart-playlist:discover, :trending)*), played (m) / unplayed (u)