share a single query pad across every database on this connection,
September 1, 2026 · View on GitHub
A terminal SQL client for Postgres, MySQL and SQLite.
Features
Write queries
- Autocomplete tables and columns in the query pad
- SQL syntax highlighting
- Run only the statement under the cursor — no selection needed
- Save and reload a query pad per connection, or open it in
$EDITOR
Explore your schema
- Browse tables, views, columns, indexes, and constraints
- View any table's data with a single keypress
- Filter tables and columns instantly
Work with results
- Filter result sets on the fly
- Inspect any row in a popup, with long values wrapped across lines
- Export to JSON or CSV
Manage connections
- Switch connections without restarting
- Switch databases on the current connection (Postgres / MySQL)
- Passwords stored securely in the OS keychain
Customise
- Configurable key bindings
- Built-in themes (kanagawa, catppuccin, rose-pine) with full colour customisation
Installation
Binary
https://github.com/wheelibin/qrypad/releases
Go install
go install github.com/wheelibin/qrypad@latest
Nix
Run without installing:
nix run github:wheelibin/qrypad
Install into your profile:
nix profile install github:wheelibin/qrypad
Or add to your flake.nix:
inputs.qrypad.url = "github:wheelibin/qrypad";
# then reference the package as:
inputs.qrypad.packages.${system}.default
Usage
qrypad
qrypad --connection <connection name>
--connection must match an entry in the config file. If omitted, you will be prompted to choose a connection on startup.
If the connection requires a password you will be prompted on first use; it is then stored in the OS keychain.
You can also switch connections from inside the app with Ctrl+K.
Config
Config is read from ~/.config/qrypad/config.toml.
Example
# query timeout (seconds)
queryTimeout = 60
# max rows fetched when viewing table data (does not apply to ad-hoc queries)
tableDataRowLimit = 100
# show horizontal borders between table rows
rowBorders = true
[theme]
name = "catppuccin"
[connections]
[connections.animals]
driver = "mysql"
host = "localhost"
port = 3306
user = "root"
database = "animals.0"
[connections.music]
driver = "postgres"
host = "localhost"
port = 5432
user = "postgres"
database = "music-store"
[connections.orders]
driver = "sqlite"
database = "db/orders.db"
[connections.warehouse]
driver = "postgres"
host = "localhost"
port = 5432
user = "postgres"
database = "warehouse"
# share a single query pad across every database on this connection,
# instead of one query pad per database (SQLite connections always
# behave this way, regardless of this setting)
singleQueryFile = true
Key bindings
Default key bindings
General
Tab/Shift+Tab— switch panels?/F1— show helpCtrl+C— quitCtrl+D— switch databaseCtrl+K— switch connectionCtrl+P— update stored passwordCtrl+B— toggle the left (tables / info) panelR— refresh schema/— filter tables (escto cancel)
Tables panel
Enter— fetch first N rows (tableDataRowLimit)D— fetch first N rows, descending]/[— switch tabsy— copy the selected table name
Table info panel
]/[— switch tabsy— copy the selected column / index name/— filter columns (escto cancel)
Query panel
F5— run the statement at the cursorCtrl+Space— autocomplete table / columnEsc— cancel a running queryCtrl+S— save the query pad (per connection)Ctrl+R— reload the saved query pad from diskCtrl+E— open the query pad in$EDITORCtrl+Z— undoCtrl+Y— redo
Results panel
Enter— open the selected row in a popupy— copy the selected value
y— copy the selected row as JSONY— copy all results as JSONCtrl+X— export results to a file/— filter results (escto cancel)
Overriding key bindings
Any of the keys below can be overridden in the config file.
[keys]
AutoComplete = ""
CancelQuery = ""
CopyResults = ""
CopyValue = ""
ExecuteQuery = ""
ExportResults = ""
FilterTable = ""
Help = ""
NextPanel = ""
NextTab = ""
OpenInEditor = ""
PrevPanel = ""
PrevTab = ""
Quit = ""
Redo = ""
RefreshSchema = ""
ReloadQuery = ""
SaveQuery = ""
SwitchConnection = ""
SwitchDatabase = ""
ToggleLeftPanel = ""
Undo = ""
UpdatePassword = ""
ViewData = ""
ViewDataDesc = ""
Themes
Built-in themes
kanagawa(default)catppuccinrose-pine
Set the active theme in the config:
[theme]
name = "catppuccin"
Customising themes
Override individual colours on top of an existing theme:
[theme]
name = "catppuccin"
borderActive = { fg = "#ff00ff" }
Or define a new theme from scratch by giving it a new name and setting the colours:
[theme]
name = "my-custom-theme"
borderActive = { bg = "", fg = "#ff00ff" }
currentStatement = { bg = "", fg = "" }
databaseSwitcherPopup = { bg = "", fg = "" }
error = { bg = "", fg = "" }
helpPopup = { bg = "", fg = "" }
helpKey = { bg = "", fg = "" }
helpDesc = { bg = "", fg = "" }
panelTitle = { bg = "", fg = "" }
panelTitleActive = { bg = "", fg = "" }
rowDetailsPopup = { bg = "", fg = "" }
spinner = { bg = "", fg = "" }
statusBar = { bg = "", fg = "" }
tableBorder = { bg = "", fg = "" }
tableHeader = { bg = "", fg = "" }
text = { bg = "", fg = "" }
titleBar = { bg = "", fg = "" }
titleBarAlt = { bg = "", fg = "" }
syntaxKeyword = { fg = "" }
syntaxString = { fg = "" }
syntaxNumber = { fg = "" }
syntaxComment = { fg = "" }
syntaxOperator = { fg = "" }
syntaxName = { fg = "" }
syntaxLiteral = { fg = "" }
syntaxPunctuation = { fg = "" }
The syntax* keys control SQL syntax highlighting colours. If omitted, they fall back to colours derived from the UI theme.
Contributing
See CONTRIBUTING.md.
License
Released under the MIT License.