3.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Tusk is a PostgreSQL database management GUI built with Tauri 2 (Rust backend) and React (TypeScript frontend).
Development Commands
npm run tauri dev # Start full app in dev mode (Vite HMR + Rust backend)
npm run dev # Start only the Vite frontend dev server (port 5173)
npm run build # Build frontend (tsc + vite build)
npm run tauri build # Build production desktop executable
npm run lint # ESLint
Rust backend builds automatically via Tauri when running npm run tauri dev/build. To check Rust compilation independently:
cd src-tauri && cargo check
Architecture
Frontend (React/TS) ──IPC invoke()──> Backend (Rust/Tauri) ──sqlx──> PostgreSQL
IPC Communication Pattern
All frontend-backend communication goes through Tauri's typed IPC. The full pipeline for adding a new backend-exposed feature:
- Rust command —
#[tauri::command]async fn insrc-tauri/src/commands/<domain>.rs - Register — add to
invoke_handlerinsrc-tauri/src/lib.rs - TS wrapper — typed
invoke()call insrc/lib/tauri.ts - React hook — TanStack React Query hook in
src/hooks/use-<domain>.ts - Types — shared interfaces in
src/types/index.ts
Backend (src-tauri/src/)
state.rs—AppState: holdsRwLock<HashMap<connection_id, PgPool>>, read-only flags, config path. Connections default to read-only.error.rs—TuskErrorenum withthiserror, serialized as string for IPC.TuskResult<T>type alias.utils.rs—escape_ident()for safe SQL identifier quoting.commands/— one module per domain (connections, queries, schema, data, export, management, history, saved_queries). Each function takesState<'_, AppState>and returnsTuskResult<T>.models/— serde-serializable structs matching TypeScript types.
SQL safety: identifiers use escape_ident(), data queries use sqlx parameterized queries. Read-only mode wraps queries in SET TRANSACTION READ ONLY + ROLLBACK.
Frontend (src/)
- State: Zustand store (
stores/app-store.ts) — connections, active connection/database, tabs, read-only flags, pg version. - Data fetching: TanStack React Query hooks in
hooks/— one hook per domain, wrappingsrc/lib/tauri.tsfunctions. - UI: shadcn/ui + Radix primitives, Tailwind CSS 4, dark mode via next-themes. SQL editor uses CodeMirror.
- Layout: resizable panels (sidebar + main area with tab bar).
Stored Data
Connections are persisted to ~/.config/tusk/connections.json. History and saved queries are stored in similar JSON files in the same config directory.
Conventions
- Frontend files: Components
PascalCase.tsx, hooksuse-kebab-case.ts, one feature per directory undercomponents/ - Path alias:
@maps to./src - Rust errors: always use
TuskErrorvariants, neverunwrap()in commands - New PG types: add conversion case in
pg_value_to_json()incommands/queries.rs