Loading...
Loading...
Open-source lightweight cross-platform database management tool built with Tauri, Vue 3, and Rust supporting MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, and SQL Server.
npx skill4agent add aradotso/trending-skills dbx-database-clientSkill by ara.so — Daily 2026 Skills collection.
xattr -cr /Applications/dbx.appgit clone https://github.com/t8y2/dbx.git
cd dbx
pnpm install
pnpm tauri dev # Development mode
pnpm tauri build # Production build → src-tauri/target/release/bundle/| Layer | Technology |
|---|---|
| Framework | Tauri 2 |
| Frontend | Vue 3 + TypeScript |
| UI | shadcn-vue + Tailwind CSS |
| Editor | CodeMirror 6 |
| Backend | Rust + sqlx / tiberius / redis-rs / mongodb |
dbx/
├── src/ # Vue 3 frontend
│ ├── components/ # UI components
│ │ ├── ConnectionForm.vue
│ │ ├── QueryEditor.vue
│ │ ├── DataGrid.vue
│ │ └── SchemaBrowser.vue
│ ├── stores/ # Pinia stores
│ ├── composables/ # Vue composables
│ └── locales/ # i18n (en, zh-CN)
├── src-tauri/ # Rust backend
│ ├── src/
│ │ ├── commands/ # Tauri commands (IPC)
│ │ ├── db/ # Database drivers
│ │ │ ├── mysql.rs
│ │ │ ├── postgres.rs
│ │ │ ├── sqlite.rs
│ │ │ ├── redis.rs
│ │ │ ├── mongodb.rs
│ │ │ ├── duckdb.rs
│ │ │ └── clickhouse.rs
│ │ └── main.rs
│ ├── Cargo.toml
│ └── tauri.conf.json
└── package.json| Field | Description |
|---|---|
| Type | MySQL / PostgreSQL / SQLite / Redis / MongoDB / DuckDB / ClickHouse / SQL Server |
| Host | Database host (e.g., |
| Port | Default port auto-fills by type |
| Database | Database/schema name |
| Username | DB user |
| Password | DB password (stored encrypted locally) |
| SSH Tunnel | Optional: host, port, user, key/password |
# MySQL / MariaDB / TiDB
mysql://user:password@localhost:3306/mydb
# PostgreSQL / openGauss / GaussDB
postgresql://user:password@localhost:5432/mydb
# SQLite (file path or drag & drop .db file)
/path/to/database.db
# Redis
redis://localhost:6379
redis://:password@localhost:6379/0
# MongoDB
mongodb://user:password@localhost:27017/mydb
mongodb+srv://user:password@cluster.mongodb.net/mydb
# ClickHouse
clickhouse://user:password@localhost:8123/default
# DuckDB
/path/to/database.duckdb| Shortcut | Action |
|---|---|
| Execute query |
| Zoom editor font size |
| Toggle comment |
| Undo |
DROPDELETETRUNCATEALTER// Environment variables used by the app (set in your shell or .env)
OPENAI_API_KEY=sk-... // OpenAI key
ANTHROPIC_API_KEY=sk-ant-... // Claude/Anthropic keyConnection
└── Database/Schema
├── Tables
│ └── table_name
│ ├── Columns (name, type, nullable)
│ ├── Indexes
│ ├── Foreign Keys
│ └── Triggers
├── Views
└── ProceduresSELECT * FROM table LIMIT 1000user:*session:*SSH Host: bastion.example.com
SSH Port: 22
SSH User: ec2-user
Auth: Key (paste private key) OR Password.db.sqlite.duckdb// src/composables/useDatabase.ts
import { invoke } from '@tauri-apps/api/core'
interface QueryResult {
columns: string[]
rows: Record<string, unknown>[]
rowsAffected: number
executionTime: number
}
export function useDatabase() {
const executeQuery = async (connectionId: string, sql: string): Promise<QueryResult> => {
return await invoke('execute_query', {
connectionId,
sql,
})
}
const testConnection = async (config: ConnectionConfig): Promise<boolean> => {
return await invoke('test_connection', { config })
}
return { executeQuery, testConnection }
}// src-tauri/src/commands/query.rs
use tauri::State;
use crate::db::ConnectionPool;
#[tauri::command]
pub async fn execute_query(
connection_id: String,
sql: String,
pool: State<'_, ConnectionPool>,
) -> Result<QueryResult, String> {
let conn = pool.get(&connection_id)
.ok_or("Connection not found")?;
conn.query(&sql).await.map_err(|e| e.to_string())
}// src-tauri/src/main.rs
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
execute_query,
test_connection,
// ... other commands
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}<!-- src/components/QueryPanel.vue -->
<script setup lang="ts">
import { ref } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import { useConnectionStore } from '@/stores/connection'
const store = useConnectionStore()
const sql = ref('')
const results = ref(null)
const error = ref('')
const loading = ref(false)
async function runQuery() {
if (!sql.value.trim()) return
loading.value = true
error.value = ''
try {
results.value = await invoke('execute_query', {
connectionId: store.activeConnectionId,
sql: sql.value,
})
} catch (e) {
error.value = String(e)
} finally {
loading.value = false
}
}
</script>
<template>
<div class="flex flex-col gap-2 h-full">
<textarea
v-model="sql"
class="font-mono text-sm border rounded p-2 h-40 resize-none"
placeholder="SELECT * FROM users LIMIT 10"
@keydown.meta.enter="runQuery"
@keydown.ctrl.enter="runQuery"
/>
<button
:disabled="loading"
class="px-4 py-2 bg-primary text-white rounded"
@click="runQuery"
>
{{ loading ? 'Running...' : 'Run (Cmd+Enter)' }}
</button>
<div v-if="error" class="text-red-500 text-sm">{{ error }}</div>
<DataGrid v-if="results" :data="results" />
</div>
</template>// src/locales/en.json
{
"connection": {
"new": "New Connection",
"test": "Test Connection",
"save": "Save"
},
"query": {
"run": "Run Query",
"history": "History"
}
}
// src/locales/zh-CN.json
{
"connection": {
"new": "新建连接",
"test": "测试连接",
"save": "保存"
}
}<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
<template>
<button>{{ t('connection.new') }}</button>
</template>[dependencies]
tauri = { version = "2", features = ["native-tls-vendored"] }
sqlx = { version = "0.7", features = ["mysql", "postgres", "sqlite", "runtime-tokio-native-tls"] }
tiberius = "0.12" # SQL Server
redis = "0.25" # Redis
mongodb = "2.8" # MongoDB
duckdb = "0.10" # DuckDB
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }xcode-select --install
# Then retry:
pnpm tauri buildbrew services listsystemctl status mysqllsof -i :5432-p 5432:5432xattr -cr /Applications/dbx.appredis://:yourpassword@localhost:6379mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/mydb?retryWrites=true&w=majoritynode --version # Must be >= 18
pnpm --version # Install: npm i -g pnpm
rustup update # Keep Rust current~/Library/Application Support/dbx/~/.local/share/dbx/%APPDATA%\dbx\# Fork & clone
git clone https://github.com/YOUR_USERNAME/dbx.git
cd dbx
pnpm install
# Create feature branch
git checkout -b feat/my-new-database-driver
# Run in dev mode with hot reload
pnpm tauri dev
# Run frontend only (no Rust)
pnpm dev
# Type check
pnpm vue-tsc --noEmit
# Submit PR to t8y2/dbx main branch