Reddish is a terminal-first Redis client built with Rust, tokio, crossterm, and ratatui.
It is designed for day-to-day Redis operations with keyboard-centric workflows: key browsing, typed value inspection, REPL execution, stats/slowlog views, Pub/Sub, and global search.
The project is under active development and tracks a milestone-driven spec (spec/reddish-tui-spec.md).
Implemented highlights:
- Key browser with namespace tree, SCAN-based loading, multi-select, and sort modes
- Typed value inspector (
string,list,hash,set,zset,stream) with editing and filtering - Set operations: union/inter/diff with multi-source selection
- ZSet score range filtering
- REPL with persistent history, command parsing, pipeline execution, and autocomplete
- REPL overlay (
:) for quick one-line commands without leaving the current tab - Info dashboard refresh loop with INFO + SLOWLOG integration, colored stats, and scrolling
- Pub/Sub publish + live subscription stream with two-panel layout
- Global search overlay with real-time SCAN-backed filtering and jump-to-key flow
- Keymap and mouse support with Vim/Emacs presets
- CLI startup overrides (
--url,--profile,--readonly,--log-level,--theme)
- Connection profiles (
standalone,cluster,sentinel) with TLS/password resolution support - Startup overrides via CLI (
--url,--profile,--readonly,--log-level,--theme)
- Key browser with namespace-aware navigation
- Multi-select with
Spaceand select-all withCtrl+A - Sort modes: alphabetical, by Redis type, by TTL (
sto cycle) - Typed Redis value loading (
string,list,hash,set,zset,stream) - Value editing, TTL editing (
t), and clipboard copy (y) - Duplicate key via
DUMP/RESTORE(d) - Set operations:
SUNIONSTORE,SINTERSTORE,SDIFFSTORE(u/i/x) - ZSet score range query (
q) with min/max filtering - Global search overlay with jump-to-key workflow (
/)
- REPL with history, parsing, pipeline execution (
;;), and tab autocomplete - REPL overlay (
:) for quick commands from any tab - Info dashboard with periodic INFO refresh, colored stats, and scrollable slowlog
- Pub/Sub tab with subscribe/unsubscribe, publish, and live message stream
- Read-only mode to block destructive writes
- Vim/Emacs-style keymaps with configurable actions
- Mouse capture and basic mouse interactions
- Context-aware clipboard copy across all value types
- Rust stable toolchain
- Redis server(s) for runtime usage
cargo build --releaseBinary will be available at target/release/reddish-tui.
# Start with default config and connection flow
cargo run
# Connect directly with URL
cargo run -- --url redis://localhost:6379/0
# Connect by saved profile name
cargo run -- --profile local-dev
# Force read-only mode
cargo run -- --readonly
# Override logging level and theme for this run
cargo run -- --log-level debug --theme nordredis-tui [OPTIONS]
--url <URL> redis://[user:pass@]host:port/db
--profile <NAME> Connect using a saved profile
--readonly Disable all write operations
--log-level <LEVEL> Override config log level
--theme <THEME> Override config theme
Config file path:
- macOS:
~/Library/Application Support/redis-tui/config.toml - Linux:
~/.config/redis-tui/config.toml
Example:
namespace_separator = ":"scan_count = 200refresh_interval_ms = 1000log_level = "info"color_scheme = "default"mouse_enabled = trueconfirm_deletes = trueConnection profiles are loaded from:
- macOS:
~/Library/Application Support/redis-tui/connections.toml - Linux:
~/.config/redis-tui/connections.toml
Reddish supports configurable keymaps and ships with Vim/Emacs-style defaults.
| Action | Vim | Emacs | Description |
|---|---|---|---|
| quit | q | Ctrl+c | Quit application |
| help | ? | ? | Show help overlay |
| palette | Ctrl+p | Ctrl+x | Open command palette |
| filter | / | Ctrl+s | Open global search |
| repl_overlay | : | Alt+; | One-line REPL prompt |
| tab_keys | 1 | Alt+1 | Keys tab |
| tab_repl | 2 | Alt+2 | REPL tab |
| tab_info | 3 | Alt+3 | Info dashboard tab |
| tab_pubsub | 4 | Alt+4 | Pub/Sub tab |
| nav_up | k / Up | Ctrl+p | Move cursor up |
| nav_down | j / Down | Ctrl+n | Move cursor down |
| nav_left | h / Left | Ctrl+b | Collapse namespace / go back |
| nav_right | l / Right | Ctrl+f | Expand namespace / go forward |
| confirm | Enter | Enter | Confirm action |
| cancel | Esc | Ctrl+g | Cancel / close overlay |
| refresh | R | Ctrl+l | Refresh key browser scan |
| copy | y | Ctrl+w | Copy context-aware value |
| Action | Vim | Emacs | Description |
|---|---|---|---|
| confirm | Enter | Enter | Inspect selected key |
| delete | D | Ctrl+d | Delete selected key |
| new_key | n | Ctrl+n | Create a new key |
| rename_key | r | Ctrl+r | Rename selected key |
| expire_key | e | Ctrl+e | Persist key (remove TTL) |
| set_ttl | t | Ctrl+t | Set TTL on selected key |
| duplicate_key | d | Ctrl+shift+d | Duplicate selected key |
| set_union | u | Ctrl+u | SUNIONSTORE with multi-select |
| set_inter | i | Ctrl+i | SINTERSTORE with multi-select |
| set_diff | x | Ctrl+d | SDIFFSTORE with multi-select |
| toggle_select | Space | Space | Toggle key selection |
| select_all | Ctrl+a | Ctrl+a | Select all visible keys |
| cycle_sort | s | Ctrl+o | Cycle sort: alpha → type → TTL |
| Action | Vim | Emacs | Description |
|---|---|---|---|
| edit | e | Ctrl+e | Edit current item |
| delete | D | Ctrl+d | Delete current item |
| copy | y | Ctrl+w | Copy current item |
| set_ttl | t | Ctrl+t | Set TTL on inspected key |
| inspector_list_push | a | Ctrl+shift+a | RPUSH to list |
| inspector_list_prepend | p | Ctrl+shift+p | LPUSH to list |
| inspector_hash_add | a | Ctrl+shift+h | Add hash field |
| inspector_set_add | a | Ctrl+shift+s | Add set member |
| inspector_zset_add | a | Ctrl+shift+z | Add zset member |
| inspector_zset_range_query | q | Ctrl+shift+q | Filter zset by score range |
| inspector_stream_add | a | Ctrl+shift+x | Add stream entry |
| inspector_toggle_view | f | Ctrl+shift+f | Toggle stream compact/full |
| inspector_goto_end | g | Ctrl+shift+g | Jump to last stream entry |
| cycle_sort | s | Ctrl+o | Toggle zset score sort asc/desc |
| Tab | Tab | Tab | Cycle string view mode |
| Action | Vim | Emacs | Description |
|---|---|---|---|
| nav_up | k / Up | Ctrl+p | Scroll slowlog up |
| nav_down | j / Down | Ctrl+n | Scroll slowlog down |
| Space | Space | Space | Toggle slowlog compact mode |
| Action | Vim | Emacs | Description |
|---|---|---|---|
| Tab | Tab | Tab | Switch channel / message input mode |
| delete | D | Ctrl+d | Unsubscribe from selected channel |
| Ctrl+L | Ctrl+l | Ctrl+l | Clear message history |
| Action | Vim | Emacs | Description |
|---|---|---|---|
| search_execute | Enter | Enter | Jump to selected key |
| search_close | Esc | Ctrl+g | Close search without action |
Run the full suite:
cargo test -qSome tests spin up local Redis instances and may print Redis startup warnings during execution.
src/app.rs— app state and event routingsrc/redis/— Redis client, typed value model, server helperssrc/ui/— UI components (keys, inspector, REPL, dashboard, pubsub, search)src/config/— config and keybinding modelssrc/events/— input/tick event streamsrc/terminal.rs— terminal lifecycle + mouse capture setuptests/— milestone-oriented integration tests
Near-term focus:
- deeper keymap coverage across all panels
- richer value editing workflows
- Pub/Sub UX refinements
- tighter spec-gate test coverage
Contributions are welcome.
Suggested workflow:
- Open an issue describing the bug/feature.
- Keep PRs small and milestone-scoped.
- Run
cargo test -qbefore submitting. - Include tests for behavior changes when possible.
MIT