SQLite terminal explorer · Rust + Ratatui

sqlens

A closer look at your database, right in the terminal. Browse tables and views, filter rows, and inspect JSON with a keyboard-driven, read-only interface.

cargo install sqlens --locked
sqlens path/to/database.sqlite
SQLens browsing eight demo products, with the table list, schema, selected row detail, and generated SQL visible.
The products table in the demo database. Select the screenshot to view it at full size.

Install and open a database

Install from crates.io with Rust 1.88+ and a C compiler. SQLite is bundled into the executable; Python and a system SQLite installation are not needed.

cargo install sqlens --locked
sqlens path/to/database.sqlite

Use the path to an existing database file. If your shell cannot find sqlens, add Cargo’s installation bin directory to your PATH, following the message printed by cargo install.

Install from a checkout

cargo install --path . --locked

Run from the checkout

cargo run --locked --release -- path/to/database.sqlite

--locked uses the dependency versions in Cargo.lock without updating it. --release builds an optimized executable. The final -- separates Cargo’s options from the database path. The binary is also available at target/release/sqlens after cargo build --locked --release.

Find your way around

  1. Choose a table or view in the left pane with ↑ and ↓.
  2. Press Enter to focus the grid. Use the arrows to select a cell.
  3. Press f to filter its column, or s to sort it.
  4. Press Enter again for full cell detail. Esc takes you back.

The right pane shows the schema, a page sized to fit the data grid, selected row detail, and the generated SQL. Resizing the terminal adjusts the page size while keeping the selected result row on screen. You can also click tables, cells, and column headers, or navigate with the mouse wheel.

Queries run in the background. You can select another table while one is loading, or press Esc from the grid to cancel. Use a terminal at least 40 columns wide and 12 rows high; larger windows show more schema and row detail.

Keyboard reference

Grid commands apply while the grid has focus. Press ? for help inside SQLens.
KeyAction
Tab / Shift+TabCycle focus forward / backward between the table list and grid.
Arrows or h j k lNavigate left, down, up, and right. Left from the first visible column returns to the table list; Right from the list focuses the grid.
EnterFocus the grid or open full cell detail.
s / SSort ascending / descending. Repeat the same key to clear that sort.
fEdit the selected column’s LIKE filter.
CClear all filters and sorting.
1–9, 0Toggle visibility of base columns 1–10.
vOpen the selector for all base columns. Use arrows and Space to toggle visibility.
+Add a SQL SELECT expression as a column.
DeleteRemove the selected expression column, including its filter and sort.
yCopy the raw selected value through the terminal clipboard.
YCopy the selected row as formatted JSON, including visible columns and expressions.
n / p or PgDn / PgUpNext / previous page, sized to fit the grid height.
Home / End or g / GFirst / last row on the current page, or first / last table. Also works in the column selector. A single g is enough.
rReload the current table’s data.
Esc / BackspaceReturn from cell detail or the grid. From a loading grid, cancel the query.
Ctrl+Q / Ctrl+CQuit from any screen, including an input or dialog.

Column indicators: ● visible, ○ hidden, ⊘ filtered, and ▲ / ▼ sorted. At least one base column stays visible.

Filter rows and add expressions

Filter a column

Select a cell and press f. Typing London applies column LIKE '%London%'. Filters on multiple columns are combined with AND.

Submit an empty input to clear that column’s filter. Spaces are preserved, and % and _ keep their SQLite wildcard meaning. Hiding a column keeps its filter active.

Filter values are bound parameters. The SQL pane shows the generated query and its parameters.

Add a calculated column

Press + and enter one expression, optionally with an explicit AS alias. For example:

UPPER(name) AS upper_name
json_extract(data, '$.id') AS json_id
CAST(price AS REAL) * quantity AS total

You can sort and filter the result like any other column. To remove it, select that expression’s column in the grid and press Delete.

Duplicate column labels are rejected. Aggregates such as COUNT(*) follow SQLite’s semantics and may collapse the result into one row.

In either input, Enter submits and Esc cancels. Unicode typing, paste, arrow-key editing, Home, End, and Ctrl+U to clear are supported. Vim navigation letters remain ordinary text in these inputs.

Inspect the full value

Press Enter on a cell to open its detail view. JSON text is automatically formatted and highlighted. Plain text is displayed literally; BLOBs are shown as hexadecimal SQL literals.

Use the arrow keys or hjkl to scroll, g / G to jump to the top/bottom, PgUp / PgDn to scroll vertically, and Ctrl + an arrow key to move to an adjacent cell on the current page. Press y to copy the raw value, or Esc to return.

Y copies the row as a JSON object from either the grid or cell detail. Hidden columns are omitted. Numbers and NULL retain their JSON types; text stays a string. BLOBs are represented as hexadecimal SQL-literal strings, and non-finite numbers as strings.

Clipboard support

Copying uses OSC 52, the terminal clipboard protocol. It can work over SSH as long as your terminal permits clipboard writes. SQLens confirms that it sent the request; the protocol does not confirm whether the clipboard changed. NULL values are copied as NULL.

Large or changing databases

Exact row counts and deep pages can still take time. SQLens caches counts across paging, sorting, and visibility changes, and invalidates them when the query source, filters, or database data version changes. Navigation and quitting stay available while the query runs.

Without an explicit sort, rows follow SQLite’s query plan. Duplicate sort values or external writes can change page boundaries. Press r to reload rows; reopen SQLens to refresh the table list.

Read-only access

SQLens opens the database with SQLite’s read-only flag and enables query_only. Filters and expressions change what you see; they do not edit the stored data.