rowdy-db 0.9.1

A fast, modern, and rowdy TUI database management tool written in Rust.
rowdy-db-0.9.1 is not a library.

🀠 Rowdy

Crates.io CI License Rust ratatui sqlx tokio tui-textarea

A fast, modern, and rowdy Terminal User Interface (TUI) database management tool written in Rust.

Rowdy is designed for developers, DBAs, and terminal enthusiasts who want to inspect, query, and manage their databases without ever leaving their terminal or touching a mouse. Built on ratatui and sqlx, it compiles into a single standalone binary with no runtime dependencies.

Rowdy demo


✨ Features

Connectors

Engine Type Feature flag URL format
PostgreSQL SQL (built-in) postgres://user:pass@host:5432/db
SQLite SQL (built-in) sqlite:///path/to/file.db
MySQL / MariaDB SQL (built-in) mysql://user:pass@host:3306/db
libsql / Turso SQL (built-in) libsql://host?authToken=TOKEN
Redis Key-value (built-in) redis://host:6379
MongoDB Document --features mongodb mongodb://user:pass@host:27017/db
DuckDB OLAP --features duckdb duckdb:///path/to/file.db

Connections & profiles

  • Saved profiles β€” ~/.config/rowdy/config.toml ; add with Ctrl+S, edit with e, delete with D
  • Encrypted credentials β€” passwords and tokens stored in the OS keychain (macOS Keychain, libsecret, Windows Credential Manager) ; __keyring__ placeholder in config file, resolved transparently at connect time
  • Pre/post-connect hooks β€” optional shell scripts per profile for SSH tunnels, VPN, proxies
  • Read-only mode β€” append ?readonly=true to any URL ; red READ-ONLY badge ; all writes blocked, filters and export still work
  • URL redaction β€” passwords and tokens masked in the UI everywhere (user:***@host, authToken=***)
  • Multi-tab sessions β€” Ctrl+T opens a new connection tab ; [/] cycles between tabs ; Ctrl+W or q closes the current tab (quits only when it is the last one) ; each tab has its own independent connection and state
  • Auto-reconnect β€” on connection loss (broken pipe, server closed, network error…), Rowdy retries up to 3 times with exponential back-off (1 s β†’ 2 s β†’ 4 s) ; yellow RECONNECTING… badge in the status bar during retries ; flash message on success or permanent failure

Data Grid

  • Infinite scroll pagination β€” 200 rows/page, next page loads on j at last row, parallel COUNT(*)
  • Cumulative column filters β€” f to filter, d to remove, F to clear all ; type-aware (= TRUE/FALSE for booleans, = n for numerics)
  • Sort by column β€” s cycles ASC / DESC / reset ; β–²/β–Ό indicator in header
  • Full-text search β€” Ctrl+F searches all loaded cells in real time ; green highlight on all matches ; n/N to navigate ; Enter keeps highlights while closing the prompt ; Esc clears ; use A first to search across all rows
  • Cursor persistence β€” row and column position preserved across filter, sort, and edit-save reloads (no jump back to row 1)
  • FK navigation β€” magenta badge on FK cells ; Enter opens a recursive sub-grid ; breadcrumb in info bar
  • Nested field navigation (MongoDB) β€” green [obj] / [arr:N] badges ; Enter drills into sub-grids recursively
  • Column resize β€” -/= in steps of 5 (min 4, max 80) ; Space collapse/expand ; cell cursor highlight
  • Preview panel β€” full value of selected cell displayed below the grid, no truncation
  • Load all β€” A fetches all rows in a single query (replaces paged data)
  • TABLE / VIEW distinction β€” [T] / [V] badges ; VIEW opens automatically read-only
  • Redis key-detail view β€” Enter on a key shows string / hash / list / set / zset content with TTL

SQL Editor

  • Multi-line editor β€” tui-textarea ; F5 / Ctrl+Enter to execute ; Ctrl+Q to exit
  • Multi-statement execution β€” splits on ;, executes sequentially, per-statement error report
  • SQL autocomplete β€” Tab triggers a floating popup with tables, columns and 80 SQL keywords ; case-insensitive matching
  • Query history β€” Alt+↑/↓ to browse ; persisted in ~/.config/rowdy/history.toml (200 entries, deduped)
  • F4 β€” opens the current SELECT result in a full read-only Data Grid

Record editing

  • Edit Record β€” field-by-field editor with full cursor, [PK] / [β†’FK] badges, live SQL preview, bool toggle with Space
  • Format validation β€” DATE / TIME / TIMESTAMP / UUID / JSON / INET / CIDR validated on exit ; red highlight + format hint ; Ctrl+S blocked while errors remain
  • Confirmation modal β€” shows the UPDATE statement before executing ; error modal on failure
  • MongoDB CRUD β€” Enter opens Edit Record for replace_one ; a inserts ; D deletes ; drill into nested [obj]/[arr] fields (Enter = sub-editor, i = raw JSON edit)

Schema & ERD

  • Schema introspection β€” PK, FK, column types on all SQL connectors (PostgreSQL pg_catalog, MySQL information_schema, SQLite/Turso PRAGMA)
  • Schema panel β€” right-hand panel in the table list showing columns with PK/FK badges and outgoing/incoming FK relations, loaded at connect time
  • ERD graph view β€” r from the table list ; star layout with the selected table at center ; bent ASCII arrows routed from the exact FK column ; j/k to navigate boxes

Export

  • CSV β€” E β†’ c ; RFC 4180, quoted fields, empty for NULL ; saved to ~/rowdy_<table>_<timestamp>.csv
  • JSON simple β€” E β†’ j ; array of typed objects
  • JSON + FK resolution β€” E β†’ J ; embeds referenced rows as <col>__ref objects, recursive up to 3 levels, cycle detection

πŸš€ Quick Start

Build from source

git clone https://github.com/TSODev/rowdy.git
cd rowdy
cargo build --release
./target/release/rowdy-db

With MongoDB support:

cargo build --release --features mongodb
./target/release/rowdy-db

With DuckDB support (statically links DuckDB C++ β€” first build takes a few minutes):

cargo build --release --features duckdb
./target/release/rowdy-db

With all optional connectors:

cargo build --release --features mongodb,duckdb
./target/release/rowdy-db

Install from crates.io

cargo install rowdy-db

With MongoDB support:

cargo install rowdy-db --features mongodb

With DuckDB support:

cargo install rowdy-db --features duckdb

βš™οΈ Configuration

Create ~/.config/rowdy/config.toml to save connection profiles:

[[connections]]
name = "Local Postgres"
type = "postgres"
url = "postgres://user:password@localhost:5432/my_db"

[[connections]]
name = "Dev SQLite"
type = "sqlite"
url = "sqlite:///home/user/dev.db"

[[connections]]
name = "Turso Cloud"
type = "libsql"
url = "libsql://your-db-org.turso.io?authToken=eyJ..."

[[connections]]
name = "Cache Redis"
type = "redis"
url = "redis://127.0.0.1:6379"

[[connections]]
name = "MySQL Local"
type = "mysql"
url = "mysql://root:password@localhost:3306/my_db"

[[connections]]
name = "Analytics DuckDB"
type = "duckdb"
url = "duckdb:///home/user/analytics.db"

Profiles appear in the left panel of the connection screen at startup.

Credential security β€” when you save a profile with Ctrl+S, Rowdy extracts the password or token from the URL and stores it in the OS keychain (macOS Keychain, libsecret on Linux, Windows Credential Manager). The URL written to config.toml uses a __keyring__ placeholder instead of the actual secret:

# What config.toml looks like after saving β€” no plaintext secrets
[[connections]]
name = "Local Postgres"
type = "postgres"
url = "postgres://user:__keyring__@localhost:5432/my_db"

Credentials are resolved transparently at connection time. On headless Linux systems without libsecret, Rowdy falls back to storing the URL unchanged and displays a warning. The feature can be disabled at build time with --no-default-features.

You can also add optional pre-connect and post-disconnect shell scripts per profile (useful for SSH tunnels, VPN, etc.):

[[connections]]
name = "VPS Postgres (SSH tunnel)"
type = "postgres"
url = "postgres://user:password@localhost:5432/mydb"
pre_connect = "ssh -f -N -L 5432:localhost:5432 user@remote-host"
post_disconnect = "pkill -f 'ssh -L 5432:localhost:5432'"

The pre_connect script runs before the database connection is established; post_disconnect runs when you disconnect or quit the app.

To connect in read-only mode (blocks all writes β€” safe for production), append ?readonly=true to any URL:

[[connections]]
name = "Production (read-only)"
type = "postgres"
url = "postgres://user:pass@prod-host/mydb?sslmode=require&readonly=true"

A red READ-ONLY badge appears in the status bar. Enter (edit record) and all DML statements in the SQL editor are disabled. Filters, pagination, and export still work normally.


⌨️ Keyboard shortcuts

Connection screen

Key Action
j / k Navigate profiles
Enter Connect to selected profile
n Enter a new connection URL
e Edit selected profile (pre-fills all fields for modification)
Tab Cycle focus between fields: DB Type β†’ URL β†’ Pre-connect β†’ Post-disconnect
← / β†’ Cycle database type when DB Type field is active
Ctrl+S Save current connection (URL + scripts) as a named profile
D Delete selected profile (with confirmation)
q Quit

Table list

Key Action
j / k Navigate tables
Enter Open table in Data Grid
e Open SQL Editor
r Open ERD graph view centered on selected table
/ Filter tables
q Disconnect

Data Grid

Key Action
j / k Next / previous row
h / l Previous / next column
g / G First / last row
PgDn / PgUp Β±10 rows
Space Collapse / expand selected column
- / = Shrink / grow selected column width (step 5)
f Open filter input for selected column
d Remove filter on selected column
F Clear all filters
s Cycle sort on selected column: ASC β†’ DESC β†’ off
A Load all rows (replaces paged data)
Ctrl+F Open full-text search prompt
n / N Next / previous search match (when search is active)
Enter FK cell β†’ open linked sub-grid ; other cell β†’ Edit Record
E Export prompt (then c=CSV, j=JSON, J=JSON+FK, Esc=cancel)
q Back to table list

Edit Record

Key Action
j / k Next / previous field
Enter Edit selected field β€” or drill into nested [obj] / [arr] (MongoDB)
i Edit selected field inline β€” on [obj] fields (MongoDB): edit raw JSON string instead of drilling in
Space Toggle boolean field (true ↔ false)
← / β†’ Move cursor within field
Home / End Jump to start / end of field
Backspace / Del Delete character
Ctrl+S Save changes β€” confirmation modal before UPDATE (SQL) or replace_one (MongoDB)
Esc / q Back to Data Grid without saving β€” or confirm nested edit and go up one level (MongoDB)

MongoDB nested editor β€” when drilling into [obj] or [arr] fields, the title shows the breadcrumb (collection β€Ί field β€Ί subfield). Press Esc at any nested level to confirm that level's edits and return to the parent. Ctrl+S is only available at the root level.

For [obj] fields specifically: Enter drills into the sub-editor; i edits the raw JSON string directly (useful when inserting a new document or when you prefer to type the JSON manually).

Array editor β€” additional keys when editing an array field:

Key Action
a Add new item at end (enters edit mode immediately)
D Delete selected item and renumber remaining items

ERD graph view (r)

Key Action
j / k or Tab Cycle between visible table boxes
Enter Re-center view on selected box (navigate the graph)
q / Esc Back to table list

The ERD view displays a star layout: the selected table in the center (yellow box), tables with incoming FK on the left (cyan), and tables referenced by outgoing FK on the right (cyan). Arrows are routed from the exact FK column line. No additional queries are made β€” the schema is reused from the panel loaded on connect.

SQL Editor

Key Action
F5 / Ctrl+Enter Execute query
F4 Open SELECT result in full Data Grid (read-only)
Alt+↑ Recall previous query from history
Alt+↓ Recall next query from history (empty = clear)
Tab Switch focus to results pane
Tab / Esc Switch focus back to editor
Ctrl+Q Back to table list

SELECT, WITH, EXPLAIN, SHOW, PRAGMA β†’ returns rows.
INSERT, UPDATE, DELETE, CREATE, … β†’ shows rows affected.

Multi-tab navigation (all screens)

Key Action
Ctrl+T Open a new connection tab
[ Switch to previous tab (when more than one tab is open, outside text-input screens)
] Switch to next tab (same condition)
Ctrl+W Close the current tab
q Close the current tab if multiple tabs are open ; quit Rowdy if it is the last tab

A tab bar appears at the top when two or more tabs are open. The active tab is highlighted in yellow.

Ctrl-C quits from anywhere.


πŸ¦† DuckDB notes

  • Supports local .db files and in-memory databases (duckdb://:memory:)
  • Native support for Parquet, CSV, and JSON files via SQL (SELECT * FROM 'data.parquet')
  • Complex types (VARCHAR[], STRUCT) are displayed as expandable nested views in the Data Grid
  • Due to a DuckDB v1.x engine limitation, UPDATE on complex-type columns (VARCHAR[], STRUCT) may fail with a FK constraint error when the table has child rows β€” use the SQL Editor as a workaround in that case

πŸ“– Full documentation

See USAGE.md for the complete user guide including connection URL formats, all keyboard shortcuts, and feature details.


πŸ”¨ Development

cargo run      # run in dev mode
cargo build    # debug build
cargo test     # run tests
cargo clippy   # lint

πŸ“œ License

Licensed under either of MIT or Apache 2.0 at your option.