███████╗ ██████╗ ██╔════╝██╔═══██╗ ███████╗██║ ██║ ╚════██║██║▄▄ ██║ ███████║╚██████╔/ ╚══════╝ ╚══▀▀═╝ Database client for vim users
A keyboard-first SQL TUI built for VIM users Bubble Tea TUI framework for Go. It focuses on speed, clarity, and terminal-native workflows—no mouse, no clutter, just efficient querying inside terminal but with the beautifull UI
Status: Active development - MySQL, PostgreSQL, and SQLite support available with full CRUD operations, foreign key navigation, pagination, and SQL query editor.
- Go 1.22 or later
go install github.com/sheenazien8/sq@latestgo mod download
go mod tidy
go build -o sq
./sqgo run .sq --help # Show help
sq --version # Show version
sq --create-connection # Create a new database connectionDatabase Support:
- MySQL database connections with full feature support
- PostgreSQL database connections with full feature support
- SQLite database file connections with full feature support
- Multiple simultaneous connections in sidebar
- Persistent connection storage
Data Browsing:
- Table listing with automatic refresh
- Data viewing with pagination (100 rows per page by default)
- Efficient handling of large datasets
- Cell-level data preview with
pkey - Copy cell data to clipboard with
ykey
Advanced Features:
- Query Editor with vim-mode support for writing and executing custom SQL queries
- SQL syntax highlighting (Chroma v2)
- SQL formatting with
Ctrl+F(sqlfmt integration) - Multi-line query support
- Query execution with F5 or Ctrl+E
- Table Structure Viewer - View columns, indexes, relations, and triggers
- Column information (type, nullable, default values)
- Index information (unique, primary, type)
- Foreign key relationships
- Triggers and their definitions
Navigation & Filtering:
- Foreign Key Navigation - Jump to related tables with
gd(goto definition) - Advanced Filtering - Multi-condition filter dialog with column/operator/value selection
- Vim-like keyboard navigation (hjkl movement, gg/G jump, w/b word movement)
- Tabbed interface for multiple tables/queries
- Collapsible sidebar to maximize table view space
UI & Theming:
- 7 built-in themes (default, dracula, nord, gruvbox, tokyo-night, catppuccin, monokai)
- Real-time theme switching with
Tkey - Multi-pane layout with sidebar, table view, and filter dialog
- Built-in help modal accessible with
?key - Responsive design that adapts to terminal size
- SQLite support
- Detail pane for selected records
- Edit/insert/delete operations
- Query history
| Key | Action |
|---|---|
? |
Show help modal |
q / Ctrl+C |
Show exit modal |
Tab |
Switch focus between sidebar and main area |
T |
Cycle themes |
s / S |
Toggle sidebar visibility |
| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
Home |
Jump to first item |
End |
Jump to last item |
Enter |
Select/connect to database or open table |
e |
Open Query Editor (requires active connection) |
d |
View table structure |
n |
Create new connection |
| Key | Action |
|---|---|
] |
Next tab |
[ |
Previous tab |
Ctrl+W |
Close current tab |
| Key | Action |
|---|---|
j / ↓ |
Move down one row |
k / ↑ |
Move up one row |
h / ← |
Scroll columns left |
l / → |
Scroll columns right |
H |
Jump to first column |
L |
Jump to last column |
J |
Next page (pagination) |
K |
Previous page (pagination) |
PgUp / PgDn |
Page up/down |
Home / End |
Jump to first/last row |
y |
Yank (copy) selected cell content to clipboard |
p |
Preview selected cell content |
/ / f |
Open filter dialog |
C |
Clear all filters |
d |
View table structure |
e |
Open Query Editor |
gd |
Go to definition (navigate to foreign key table) |
| Key | Action |
|---|---|
1 |
View Columns |
2 |
View Indexes |
3 |
View Relations |
4 |
View Triggers |
Tab |
Next section |
Shift+Tab |
Previous section |
The query editor features full vim-mode support for efficient editing.
| Mode | Description |
|---|---|
NORMAL |
Navigation and commands (default) |
INSERT |
Text editing mode |
| Key | Action |
|---|---|
i |
Enter insert mode at cursor |
a |
Enter insert mode after cursor |
I |
Enter insert mode at beginning of line |
A |
Enter insert mode at end of line |
o |
Open new line below and enter insert mode |
O |
Open new line above and enter insert mode |
h / ← |
Move cursor left |
j / ↓ |
Move cursor down |
k / ↑ |
Move cursor up |
l / → |
Move cursor right |
0 |
Move to beginning of line |
$ |
Move to end of line |
w |
Move to next word |
b |
Move to previous word |
g |
Go to beginning of document |
G |
Go to end of document |
x |
Delete character under cursor |
X |
Delete character before cursor |
u |
Undo |
| Key | Action |
|---|---|
Esc |
Return to normal mode |
| Any key | Type text |
| Key | Action |
|---|---|
F5 / Ctrl+E |
Execute query |
Ctrl+R |
Toggle focus between editor and results |
Ctrl+F |
Format SQL query |
Ctrl+Y |
Copy entire query to clipboard |
| Key | Action |
|---|---|
h/j/k/l |
Navigate cells |
p |
Preview selected cell content |
y |
Yank (copy) selected cell to clipboard |
i / a |
Return to editor in insert mode |
Ctrl+R |
Return to editor |
| Key | Action |
|---|---|
Tab / → / l |
Next field |
Shift+Tab / ← / h |
Previous field |
j / ↓ |
Next option (column/operator) |
k / ↑ |
Previous option (column/operator) |
Enter |
Apply filter and close |
Esc |
Close without applying |
Ctrl+C |
Clear filter |
| Key | Action |
|---|---|
← / → / h / l / Tab |
Switch button |
Enter |
Confirm selection |
y / Y |
Yes |
n / N / Esc |
No |
sq/
├── main.go # Entry point, initializes Bubble Tea program
├── app/ # Main application logic (Bubble Tea Model-View-Update)
│ ├── init.go # Init() - initialization command
│ ├── model.go # Model struct and constructor
│ ├── update.go # Update() - handles messages and input
│ └── view.go # View() - renders the UI
├── config/ # Application configuration
│ └── config.go # Config loading/saving (~/.config/sq/config.json)
├── drivers/ # Database drivers
│ ├── driver.go # Driver interface definition
│ ├── mysql.go # MySQL driver implementation (with pagination support)
│ ├── postgres.go # PostgreSQL driver implementation (with pagination support)
│ └── types.go # Shared types (TableStructure, ColumnInfo, Pagination, etc.)
├── logger/ # Logging utilities
├── storage/ # Connection storage utilities
├── ui/ # UI components (separate Bubble Tea models)
│ ├── sidebar/ # Connection and table list sidebar
│ ├── table/ # Scrollable table widget
│ ├── tab/ # Tabbed interface for multiple views
│ ├── filter/ # Filter input component
│ ├── query-editor/ # SQL query editor with vim-mode and formatter
│ ├── syntax-editor/ # Syntax highlighting text editor component
│ ├── modal/ # Base modal component
│ ├── modal-exit/ # Exit confirmation modal
│ ├── modal-cell-preview/ # Cell content preview modal
│ ├── modal-create-connection/ # New connection modal
│ ├── modal-help/ # Help modal with all keybindings
│ ├── theme/ # Theme system and color definitions
│ ├── main/ # (future) Main record view
│ └── detail/ # (future) Detail pane
└── demo/ # Demo files
└── demo.mov # Demonstration video
The app follows Bubble Tea's Model-View-Update (MVU) architecture:
- Model: Application state with sub-models for each UI component
- Update: Event handling, routing messages to focused components
- View: Rendering, composing sub-component views using Lipgloss
- Init: Initial commands (currently nil)
Each UI component (sidebar, table, filter, modal) follows the same pattern with own Model, Update(), and View() methods.
Configuration is saved to ~/.config/sq/config.json:
{
"theme": "default"
}Available themes: default, dracula, nord, gruvbox, tokyo-night, catppuccin, monokai.
Connections are stored in ~/.config/sq/storage.db.
-
Launch the application:
./sq
-
Press
nto create a new connection -
Select your database driver (MySQL or PostgreSQL)
-
Enter your connection details:
- Name: A descriptive name for this connection (e.g., "Production DB")
- Host: Database server address (default: localhost)
- Port: Database port (MySQL: 3306, PostgreSQL: 5432)
- Username: Database user (MySQL: root, PostgreSQL: postgres)
- Password: User password
- Database: Database name to connect to
-
Press
Enterto test the connection and save it -
Once saved, your connection appears in the sidebar and can be selected with
Enter
-
MySQL - Full support including:
- Table browsing and data viewing with pagination
- Table structure (columns, indexes, relations, triggers)
- Foreign key navigation (goto definition)
- Custom SQL query execution with syntax highlighting and formatting
- Filtering with multiple conditions
- Connection persistence
-
PostgreSQL - Full support including:
- Table browsing and data viewing with pagination
- Table structure (columns, indexes, relations, triggers)
- Foreign key navigation (goto definition)
- Custom SQL query execution with syntax highlighting and formatting
- Filtering with multiple conditions
- Connection persistence
MySQL:
mysql://user:password@tcp(host:port)/database
Example:
mysql://root:password@tcp(localhost:3306)/mydb
PostgreSQL:
postgres://user:password@host:port/database?sslmode=disable
Example:
postgres://postgres:password@localhost:5432/mydb?sslmode=disable
sq automatically detects and uses the appropriate schema:
-
Priority Order:
- First, checks if the
publicschema exists and uses it - If
publicdoesn't exist, uses the first user-created schema found - Falls back to
publicif detection fails
- First, checks if the
-
Schema Detection:
- Automatically excludes PostgreSQL system schemas (
pg_catalog,information_schema,pg_toast) - Selects the first user-accessible schema alphabetically
- Detection happens automatically on connection
- Automatically excludes PostgreSQL system schemas (
-
Current Limitations:
- Only one schema is supported per connection
- Tables from multiple schemas cannot be viewed simultaneously
- To work with tables in different schemas, create separate connections for each schema
If you need to work with a specific non-public schema, the schema is automatically detected on connection. If detection doesn't find your schema, ensure:
- The schema exists in the database
- Your user has permissions to access it
- The schema is not a PostgreSQL system schema
Error: "invalid database scheme"
- Make sure you're using the correct URI format for your database type
- MySQL:
mysql://user:password@host:port/database - PostgreSQL:
postgres://user:password@host:port/database?sslmode=disable
PostgreSQL: "relation not found"
- Check that your tables exist in the detected schema (see logs for which schema was selected)
- Verify the table names match exactly (PostgreSQL is case-sensitive for unquoted identifiers)
- If using a non-public schema, ensure:
- The schema exists in your database
- Your user has SELECT permissions on the schema
- The schema is not a PostgreSQL system schema (
pg_catalog,information_schema,pg_toast)
- Check
~/.config/sq/debug.logto see which schema was automatically detected
Connection refused
- Check that the database server is running and accessible
- Verify host and port are correct
- Check firewall rules if connecting to remote servers
- Ensure username and password are correct
Debug logs are written to ~/.config/sq/debug.log when the DEBUG environment variable is set to true. This can be helpful for troubleshooting connection issues or unexpected behavior.
To enable detailed logging:
- Run sq with
DEBUG=true sq - Check the
~/.config/sq/debug.logfile - Look for error messages related to your specific operation
- Common issues like schema problems, query errors, and connection failures are logged here
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests (when implemented)
- Submit a pull request
This project is open source. See LICENSE file for details.
