Your database,
in your terminal.
floz-editor is a production-grade TUI for PostgreSQL. Browse schemas, CRUD rows, filter data, navigate foreign keys, and manage connections — all without leaving your terminal.
Data Grid
Horizontal scroll, column resize, reorder. Deterministic pagination with 100-row chunks.
Schema Explorer
Collapsible schema tree with lazy-loaded tables. Navigate with vim keys or arrows.
Dual Filtering
Global fuzzy search (/) and structured filter builder (F) with 7 operators per column.
Full CRUD
Create, edit, and delete rows with primary-key-bound mutations. Read-only mode for safety.
FK Navigation
Expand parent rows to child data. Jump into related tables with breadcrumb tracking.
Session Persistence
Remembers last schema, table, column widths, and ordering across restarts.
Installation
# From source (requires Rust toolchain)
git clone https://github.com/hanuman-org/floz-editor.git
cd floz-editor
cargo install --path .
# Or build directly
cargo build --release
./target/release/floz-editor --url postgres://localhost/mydb
Quick Start
# Minimal — connects using DATABASE_URL env var
floz-editor
# Specify connection URL
floz-editor --url postgres://user:pass@localhost:5432/mydb
# Read-only mode (safe for production)
floz-editor --url postgres://prod-host/db --read-only
# Start in a specific schema
floz-editor --schema accounting
# Custom config file
floz-editor --config ./my-editor.toml
# Color theme
floz-editor --theme dracula
Data Grid
The primary view. Displays table data in a scrollable grid with column metadata, pagination, and dynamic OID-based type decoding.
Navigation
j / ↓ move cursor down k / ↑ move up ← → scroll columns horizontally
Column Operations
Alt+← / Alt+→ resize column width Ctrl+← / Ctrl+→ reorder columns (swap)
Pagination
Rows load in 100-row chunks. As you scroll near the bottom, floz-editor automatically pre-fetches the next chunk — seamless infinite scrolling with deterministic offset-based pagination.
Dynamic Type Decoding
Columns are decoded dynamically from PostgreSQL OIDs at runtime — no compile-time schema needed. Supports all standard types: int4, text, bool, timestamptz, uuid, jsonb, numeric, arrays, and more. Long values are truncated to keep the grid readable.
Schema Explorer
Press h or ← from the data grid to open the left-pane schema tree.
Schemas are discovered from information_schema.schemata (excluding internal PG schemas). Tables are lazy-loaded when a schema node is expanded. Tables are marked with PK status for mutability awareness.
Controls
j / k navigate Enter expand schema or select table l / → / Esc return to grid
System schemas (pg_catalog, information_schema, pg_toast) are automatically hidden. Additional schemas can be hidden via hidden_schemas in the config file.
Filtering
Fuzzy Search /
Press / to enter filter mode. Type a search term — it's applied as a global ILIKE '%term%' across all text-castable columns. Press Enter to apply, Esc to cancel.
Advanced Filter Builder F
Press F to open the structured filter modal. Build complex queries with per-column conditions:
| Operator | SQL | Description |
|---|---|---|
| Exact | = | Exact match |
| Contains | ILIKE '%..%' | Case-insensitive substring |
| Not Equal | != | Not equal |
| Greater Than | > | Greater than |
| Less Than | < | Less than |
| Is Null | IS NULL | Null check |
| Is Not Null | IS NOT NULL | Non-null check |
Multiple conditions are joined with AND / OR gates (toggleable). Navigate with j/k for rows and h/l for columns.
CRUD Operations
All write operations are PK-bound for safety. Tables without primary keys are automatically detected as read-only.
Create Row n
Opens a form with all columns. Tab/Shift+Tab to navigate fields. Ctrl+N to toggle NULL. Enter to submit, Esc to cancel.
Edit Row Enter
Opens an edit form pre-filled with the current row values. Only modified fields are included in the UPDATE.
Delete Row d
Shows a confirmation prompt. Press y to confirm, any other key to cancel. DELETE is bound to the row's primary key.
Read-only mode: Launch with --read-only to disable n, d, and Enter mutation keys entirely. PK-less tables are automatically read-only.
Child Expansion & FK Navigation
Foreign keys are auto-discovered from pg_constraint. Supports single and composite FK relationships.
Expand Child Pane Tab
Press Tab to open the child split-pane showing related records for the selected row. Press Tab again to cycle through FK relations if a table has multiple.
Jump Into Child Table l
With the child pane open, press l to navigate into the child table. The current position is pushed onto a breadcrumb stack.
Go Back Esc / b
Pop the breadcrumb stack and return to the parent table with the previous filter and cursor position.
Child rows are cached using a DashMap-based concurrent cache, with manual invalidation on r (refresh).
Keybindings
| Key | Mode | Action |
|---|---|---|
| q / Ctrl+c | Global | Quit |
| ? | Normal | Toggle help modal |
| j / ↓ | Normal | Move cursor down |
| k / ↑ | Normal | Move cursor up |
| ← / → | Normal | Scroll columns |
| h | Normal | Open schema explorer |
| Alt+← / Alt+→ | Normal | Resize column |
| Ctrl+← / Ctrl+→ | Normal | Reorder columns |
| / | Normal | Fuzzy filter mode |
| F | Normal | Advanced filter builder |
| n | Normal | New row form |
| Enter | Normal | Edit row form |
| d | Normal | Delete row (confirm) |
| r / F5 | Normal | Refresh data + clear cache |
| Tab | Normal | Toggle/cycle child FK pane |
| l | Normal | Jump into child table |
| b / Esc | Normal | Go back (breadcrumb pop) |
| e | Normal | Dismiss error bar |
| S | Normal | Server stats panel |
| C | Normal | Active connections panel |
| Ctrl+N | Form | Toggle NULL on field |
| Tab | Form | Next field |
| Shift+Tab | Form | Previous field |
Configuration
Configuration via floz-editor.toml in the current directory (or --config path).
# floz-editor.toml
[database]
url = "postgres://user:pass@localhost:5432/mydb"
[editor]
read_only = false
default_schema = "public"
hidden_schemas = ["pg_catalog", "information_schema"]
nerd_font = true
Priority Resolution
Database URL: --url CLI → [database] url TOML → DATABASE_URL env var.
Schema: --schema CLI → default_schema TOML → "public".
Read-only: --read-only CLI ∨ read_only TOML.
Session Persistence
floz-editor saves your session to ~/.config/floz-editor/session.toml containing:
- last_schema / last_table — resume where you left off
- expanded_schemas — which tree nodes were open
- custom_col_widths — per-column width overrides
- custom_col_order — per-table column reordering
Disable with --no-session.
Server Stats & Connections
Server Stats S
View PostgreSQL version, uptime, database size, active backends, cache hit ratio, and system resources.
Active Connections C
View all active database connections from pg_stat_activity. Navigate with j/k and kill connections with k. The editor sets application_name = 'floz-editor' for easy identification.
Architecture
floz-editor/src/
├── main.rs ← CLI parsing, pool setup, entry point
├── config.rs ← Cli + Config + Session structs
├── channel.rs ← Tokio MPSC Action enum
├── app/
│ ├── mod.rs ← Main event loop (render + dispatch)
│ ├── state.rs ← AppState (all TUI state)
│ ├── events.rs ← Action → side-effect handlers
│ └── input.rs ← Keyboard input → Action dispatch
├── db/
│ ├── introspect.rs ← Schema/table/PK/FK discovery
│ ├── decode.rs ← Dynamic OID-based row decoding
│ └── worker.rs ← Background DB queries (non-blocking)
├── ui/ ← Ratatui widgets
│ ├── grid.rs, explorer.rs, form.rs, footer.rs
│ ├── confirm.rs, help.rs, stats.rs, connections.rs
│ ├── child.rs, advanced_search.rs
├── mutation.rs ← Form state + mutation payload builder
├── cache.rs ← DashMap child-data cache
├── types.rs ← Shared types (Row, ColumnMeta, etc.)
├── telemetry.rs ← Server stats + pg_stat_activity
└── logger.rs ← 30-day rotating tracing logs
Non-Blocking Architecture
All database operations run on a separate Tokio task via an MPSC channel (Action enum). The TUI render loop never blocks. Results are sent back through the same channel and applied to AppState on the main thread.
Dependencies
Logging
floz-editor writes structured logs using tracing + tracing-appender with 30-day automatic rotation. Logs are written to ~/.config/floz-editor/logs/.
Log level is controlled via the RUST_LOG environment variable: RUST_LOG=debug floz-editor.