MIT Rust

Fast, vim-native SQL client.

No Electron. No JVM. No bullshit.

Native Rust. Instant startup. Terminal-native. MySQL, Postgres, SQLite, DuckDB.

sqeel — shop
Explorer — (6)
> analytics
> billing
v shop
   v users
     id: bigint(20)
     email: varchar
     name: varchar
     status: varchar
     created_at: timestamp
   > orders
   > products
   > sessions
> mysql
> information_schema
scratch_001.sql
select * from shop.users
Results (188 rows)
select * from shop.users

id   is_active  first_name  last_name   email              status
101  true       Ada         Lovelace    ada@sample.com     active
102  true       Grace       Hopper      grace@sample.com   active
103  false      Alan        Turing      alan@sample.com    pending
104  true       Linus       Torvalds    linus@sample.com   active
105  false      Margaret    Hamilton    mh@sample.com      inactive
NORMAL shop :: scratch_001.sql

why

Everything a keyboard-driven DB jockey wants.

01 — CORE

Native Rust

Instant startup. No JVM, no Node, no runtime tax. Small binary, small RSS.

02 — INPUT

First-class vim

Normal/insert/visual/command modes. Search, leader chords, query history via Ctrl+P/Ctrl+N.

03 — TUI

Terminal UI

sqeel — ratatui terminal client. Instant startup, no Electron, no JVM.

04 — DB

MySQL · Postgres · SQLite · DuckDB

Powered by sqlx + duckdb-rs. Per-file TOML connections, live switcher. A duckdb: URL (file or duckdb::memory:) puts DuckDB's own reach at your fingertips — SELECT * FROM 'data.csv' over CSV / Parquet, no import step.

05 — TABS

Per-tab connections

Each editor tab binds to its own database. Switching tabs swaps warm connection pools without reconnecting, in-flight queries on other connections keep running, and bindings survive a restart. Tabs pointed somewhere other than the active connection carry a dim [conn] suffix, so "which database is this about to hit" is a glance, not a guess.

06 — SECRETS

OS keyring credentials

Passwords land in Secret Service / Keychain / Credential Manager — never plaintext on disk. :migrate-secrets walks existing connections and moves inline passwords into the keyring.

07 — LSP

sqls integration

Completions, inline diagnostic underlines, and gutter signs from any SQL LSP, with an auto-generated sqls config from the active connection. K hovers (markdown + GFM tables), gd goes to definition, errors jump the editor to line:col. No sqls on $PATH? :Anvil install sqls fetches it into a local store — or turn the offer off with editor.lsp_auto_install = false.

08 — SYNTAX

tree-sitter highlighting

Dialect-aware. Fast, accurate, no regex soup.

09 — HISTORY

Editor tabs + history picker

Lazy load, 5-minute RAM eviction. Auto-save SQL buffers. Query history is kept per connection; <leader>h opens a fuzzy picker over it and drops the selection in a fresh scratch tab.

10 — RESULTS

Vim-native results pane

Cell cursor with counts, / search, visual-line and visual-block selection with TSV yank, mouse drag-select. SQL NULL stays distinct from empty text in the table, JSON, and CSV output.

11 — GUARD

Destructive-statement guard

UPDATE/DELETE with no top-level WHERE, plus DROP and TRUNCATE, ask for an explicit y/N first. Ctrl+C cancels a running query or batch mid-flight.

12 — HEADLESS

-e for scripts and CI

sqeel -e "SELECT 1" --format table|csv|json runs statements with no TUI. Summaries go to stderr so stdout stays pure data for pipes; first error exits 1.

13 — EX

:export · :describe · :refresh

:export csv|json [path] writes the active result tab to disk. :describe <table> dumps dialect-aware column schema. :refresh / <leader>R busts the schema cache without reconnecting.

14 — PANES

tmux-aware nav

Ctrl+HJKL across schema / editor / results. Mouse works everywhere too.

15 — SCHEMA

Schema browser

Expand DB → tables → columns with types inline. Click or keyboard, fuzzy search across objects.

16 — SANDBOX

--sandbox to try it

Launches in a fresh tempdir that never touches your real config, seeded with a SQLite connection and a sample buffer. Bare sqeel with $DATABASE_URL set prompts y/N (password masked) instead of showing the picker.

17 — LIMIT

Auto-LIMIT on bare SELECTs

A SELECT that doesn't limit itself gets LIMIT 100 appended, so a fat table never freezes the pane. When the cap is what you're seeing, the result tab says first N rows — auto LIMIT and headless mode notes it on stderr. Tune or disable with editor.default_row_limit.

install

Prebuilt binaries on every tagged release.

macOS via Homebrew tap, Arch via AUR, crates.io, or grab a prebuilt binary. Linux (x86_64, aarch64, musl), macOS (Apple Silicon, Intel), Windows (x86_64). Arch users: AUR sqeel-bin. Alpine: the musl tarball is a static drop-in (the .apk is built by the same pipeline but didn't make the last tag). SHA-256 sidecars on every artifact, plus a completions-man tarball — bash, zsh, fish, powershell, elvish, and nushell completions and a man page, all generatable from the binary itself (sqeel --completions zsh, sqeel --man).

sqeel — macOS (Homebrew)
$ brew install kryptic-sh/tap/sqeel
$ sqeel
sqeel — Arch Linux (AUR)
$ yay -S sqeel-bin
$ paru -S sqeel-bin
sqeel — Alpine / musl
# grab sqeel-<tag>-x86_64-unknown-linux-musl.tar.gz from
# https://github.com/kryptic-sh/sqeel/releases/latest — static, no libc chase
$ tar xzf sqeel-*-x86_64-unknown-linux-musl.tar.gz
$ install -m755 sqeel /usr/local/bin/sqeel
sqeel — from source
# crates.io — the published crate can trail the newest tag
$ cargo install sqeel

# or build from the repo
$ git clone https://github.com/kryptic-sh/sqeel
$ cd sqeel
$ cargo build --release

# binary in target/release/sqeel