A lightweight database client for Neovim. Query databases directly from your editor.


┌─────────────────────┬─────────────────────────────────────┐
│ Sidebar (20%) │ Query Editor (80%) │
├─────────────────────┼─────────────────────────────────────┤
│ History (20%) │ Result Viewer (80%) │
└─────────────────────┴─────────────────────────────────────┘

┌─────────────────────┬─────────────────────┬───────────────┐
│ Sidebar (33%) │ Query Editor (34%) │ History (33%) │
├───────────────────────────────────────────────────────────┤
│ Result Viewer (100%) │
└───────────────────────────────────────────────────────────┘
psql for PostgreSQLmysql for MySQL/MariaDBsqlite3 for SQLiteexecutor = "dadbod"){
"zerochae/dbab.nvim",
dependencies = {
"MunifTanjim/nui.nvim",
"nvim-lua/plenary.nvim", -- Optional: for async execution
"tpope/vim-dadbod", -- Optional: for executor = "dadbod"
"hrsh7th/nvim-cmp", -- Optional: for autocompletion
},
config = function()
require("dbab").setup({
connections = {
{ name = "local", url = "postgres://user:pass@localhost:5432/mydb" },
{ name = "prod", url = "$DATABASE_URL" }, -- supports env vars
},
})
end,
}
If you use nvim-cmp, add dbab to your sources to enable SQL autocompletion (tables, columns, keywords):
require("cmp").setup({
sources = {
{ name = "dbab" },
-- other sources...
},
})
| Command | Description |
|---|---|
:Dbab |
Open dbab sidebar |
:DbabClose |
Close dbab |
| Key | Action |
|---|---|
<CR> / o |
Toggle node / Open query |
<Tab> |
Move to editor |
S |
Select table (SELECT *) |
i |
Insert table (INSERT template) |
d |
Delete saved query |
q |
Close |
| Key | Action |
|---|---|
<CR> |
Execute query |
<C-s> |
Save query |
gt / gT |
Next / Previous tab |
<Leader>w |
Close tab |
<Tab> |
Move to result |
q |
Close |
| Key | Action |
|---|---|
<CR> |
Load or execute query (based on config) |
R |
Re-execute query immediately |
y |
Copy query to clipboard |
d |
Delete entry |
C |
Clear all history |
<Tab> |
Move to sidebar |
<S-Tab> |
Move to result |
q |
Close |
| Key | Action |
|---|---|
y |
Yank current row as JSON |
Y |
Yank all rows as JSON |
<Tab> |
Move to sidebar |
<S-Tab> |
Move to editor |
q |
Close |



require("dbab").setup({
connections = {
{ name = "local", url = "postgres://localhost/mydb" },
},
executor = "cli", -- "cli" (self-contained) | "dadbod" (requires vim-dadbod)
layout = "classic", -- "classic" | "wide" | custom layout table
sidebar = {
width = 0.2,
use_brand_icon = false, -- true: per-DB icons, false: generic db icon
use_brand_color = false, -- true: per-DB brand colors, false: single color (Number)
show_brand_name = false, -- true: show [postgres] label, false: icon + name only
show_system_schemas = true,
},
editor = {
show_tabbar = true, -- show tab bar above editor
},
result = {
max_width = 120,
max_height = 20,
show_line_number = true,
header_align = "fit", -- "fit" or "full"
style = "table", -- "table", "json", "raw", "vertical", "markdown"
},
history = {
width = 0.2,
style = "compact", -- "compact" or "detailed"
max_entries = 100,
on_select = "execute", -- "execute" or "load"
persist = true,
filter_by_connection = true,
query_display = "auto", -- "short", "full", or "auto"
short_hints = { "where", "join", "order", "group", "limit" },
},
keymaps = {
open = "<Leader>db",
execute = "<CR>",
close = "q",
sidebar = {
toggle_expand = { "<CR>", "o" },
refresh = "R",
rename = "r",
new_query = "n",
copy_name = "y",
insert_template = "i",
delete = "d",
copy_query = "c",
paste_query = "p",
to_editor = "<Tab>",
to_history = "<S-Tab>",
},
history = {
select = "<CR>",
execute = "R",
copy = "y",
delete = "d",
clear = "C",
to_sidebar = "<Tab>",
to_result = "<S-Tab>",
},
editor = {
execute_insert = "<C-CR>",
execute_leader = "<Leader>r",
save = "<C-s>",
next_tab = "gt",
prev_tab = "gT",
close_tab = "<Leader>w",
to_result = "<Tab>",
to_sidebar = "<S-Tab>",
},
result = {
yank_row = "y",
yank_all = "Y",
to_sidebar = "<Tab>",
to_editor = "<S-Tab>",
},
},
highlights = {
-- Override any Dbab highlight group
-- DbabHeader = { bg = "#ff6600", fg = "#000000" },
},
})
| Preset | Description |
|---|---|
"classic" |
4-pane layout (sidebar 20%, history 20%) |
"wide" |
3-column top + full-width bottom (sidebar 33%, history 33%) |
Define your own pane arrangement:
-- No history panel
layout = {
{ "sidebar", "editor" },
{ "result" },
}
-- Editor on the left
layout = {
{ "editor", "sidebar" },
{ "result", "history" },
}
Components: "sidebar", "editor", "history", "result" (editor and result are required)
Configure with result.style:
| Style | Description |
|---|---|
"table" |
Table with zebra striping and type-aware highlighting (default) |
"json" |
JSON format with Treesitter syntax highlighting |
"vertical" |
One record per block, column names on the left (like psql \x) |
"markdown" |
Markdown table with Treesitter syntax highlighting |
"raw" |
Unprocessed CLI output |
result = {
style = "vertical",
},





Configure with history.style:
| Style | Description |
|---|---|
"compact" |
One line per entry with verb, target, hints (default) |
"detailed" |
Multi-line: full query with syntax highlighting + metadata below |
history = {
style = "detailed",
},
Control how database connections appear in the sidebar:
sidebar = {
use_brand_icon = false, -- default
use_brand_color = false, -- default
show_brand_name = false, -- default
},
| Option | false (default) |
true |
|---|---|---|
use_brand_icon |
Generic DB icon for all connections | Per-DB brand icons (PostgreSQL, MySQL, etc.) |
use_brand_color |
Single color (Number highlight) |
Per-DB brand colors (blue, red, green, etc.) |
show_brand_name |
icon my_db |
icon [postgres] my_db |
All highlight groups can be overridden by defining them before setup().
Groups marked with (computed) are always recalculated based on your colorscheme.
| Group | Default | Description |
|---|---|---|
DbabRowOdd |
(computed) | Odd row background |
DbabRowEven |
(computed) | Even row background |
DbabHeader |
(computed) | Result header (from Function fg) |
DbabSeparator |
Comment |
Result separator lines |
DbabCellActive |
CursorLine |
Active cell |
| Group | Default | Description |
|---|---|---|
DbabFloat |
NormalFloat |
Float window background |
DbabBorder |
WinSeparator |
Window border |
DbabTitle |
Title |
Window title |
| Group | Default | Description |
|---|---|---|
DbabNull |
Comment |
NULL values |
DbabNumber |
Number |
Numeric values |
DbabString |
Normal |
String values |
DbabBoolean |
Boolean |
Boolean values |
DbabDateTime |
Special |
Date/time values |
DbabUuid |
Constant |
UUID values |
DbabJson |
Function |
JSON values |
| Group | Default | Description |
|---|---|---|
DbabTable |
Type |
Table names |
DbabKey |
Keyword |
Key names |
DbabPK |
ErrorMsg |
Primary key (bold) |
DbabFK |
Function |
Foreign key (bold) |
| Group | Default | Description |
|---|---|---|
DbabIconDb |
Number |
Default DB icon color (use_brand_color = false) |
DbabIconPostgres |
fg=#4169E1 |
PostgreSQL brand color (bold) |
DbabIconMysql |
fg=#4479A1 |
MySQL brand color (bold) |
DbabIconMariadb |
fg=#003545 |
MariaDB brand color (bold) |
DbabIconSqlite |
fg=#003B57 |
SQLite brand color (bold) |
DbabIconRedis |
fg=#FF4438 |
Redis brand color (bold) |
DbabIconMongodb |
fg=#47A248 |
MongoDB brand color (bold) |
DbabSidebarIconConnection |
Number |
Connection icon |
DbabSidebarIconActive |
String |
Active connection icon |
DbabSidebarIconNewQuery |
Function |
New query icon |
DbabSidebarIconBuffers |
Function |
Buffers icon |
DbabSidebarIconSaved |
Keyword |
Saved queries icon |
DbabSidebarIconSchemas |
Special |
Schemas icon |
DbabSidebarIconSchema |
Type |
Schema icon |
DbabSidebarIconTable |
Type |
Table icon |
DbabSidebarIconColumn |
Function |
Column icon |
DbabSidebarIconPK |
ErrorMsg |
Primary key icon |
DbabSidebarText |
Normal |
Default text |
DbabSidebarTextActive |
String |
Active item text (bold) |
DbabSidebarType |
Comment |
Type annotation |
| Group | Default | Description |
|---|---|---|
DbabHistoryHeader |
Title |
Section header (bold) |
DbabHistoryRowOdd |
(computed) | Odd row background |
DbabHistoryRowEven |
(computed) | Even row background |
DbabHistoryTime |
Comment |
Timestamp |
DbabHistoryVerb |
Keyword |
SQL verb |
DbabHistoryTarget |
Type |
Target table name |
DbabHistoryDuration |
Number |
Execution duration |
DbabHistoryConnName |
Normal |
Connection name |
DbabHistorySelect |
Function |
SELECT queries |
DbabHistoryInsert |
String |
INSERT queries |
DbabHistoryUpdate |
Type |
UPDATE queries |
DbabHistoryDelete |
ErrorMsg |
DELETE queries |
DbabHistoryCreate |
String |
CREATE statements |
DbabHistoryDrop |
ErrorMsg |
DROP statements |
DbabHistoryAlter |
Special |
ALTER statements |
DbabHistoryTruncate |
WarningMsg |
TRUNCATE statements |
Hint badges (compact mode):
| Group | Default | Description |
|---|---|---|
DbabHistoryHintWhere |
WarningMsg |
WHERE clause |
DbabHistoryHintJoin |
Special |
JOIN clause |
DbabHistoryHintOrder |
Keyword |
ORDER BY |
DbabHistoryHintGroup |
Type |
GROUP BY |
DbabHistoryHintLimit |
Number |
LIMIT |
| Group | Default | Description |
|---|---|---|
DbabTabActive |
bg=#3a3a4a |
Active tab (bold) |
DbabTabActiveIcon |
bg=#3a3a4a fg=#a6e3a1 |
Active tab icon |
DbabTabInactive |
Comment |
Inactive tab |
DbabTabInactiveIcon |
Comment |
Inactive tab icon |
DbabTabModified |
WarningMsg |
Modified indicator |
DbabTabIconSaved |
String |
Saved query icon |
DbabTabIconUnsaved |
Function |
Unsaved query icon |
DbabTabbarBg |
Normal |
Tab bar background |
Override highlights via setup():
require("dbab").setup({
highlights = {
DbabHeader = { bg = "#ff6600", fg = "#000000" },
DbabNull = { fg = "#555555", italic = true },
},
})
postgres://user:password@host:port/database
mysql://user:password@host:port/database
mariadb://user:password@host:port/database
sqlite:///path/to/database.db
Environment variables are supported: $DATABASE_URL or ${DATABASE_URL}
This project was inspired by excellent existing plugins:
dbab.nvim aims to provide a lightweight, self-contained alternative with a modern Lua-based UI. It can optionally integrate with vim-dadbod via executor = "dadbod".
MIT