The idea
A desktop SQL client that treats every connection as having a risk level. Point it at your local database and it behaves like any other client. Point it at production and it changes: destructive statements get an estimated row count before they run, every write opens inside an explicit transaction you have to commit yourself, and each statement is appended to a local audit log with the reason you typed when you opened the connection. Same editor, same autocomplete, different rules depending on where you're pointed.
Why build this
The standard database GUIs are environment-blind. The connection dropdown is a colored dot, and the difference between staging and production is one careless click. Everyone who has run a database console for a few years has a story — the UPDATE with the WHERE clause still highlighted, the DELETE fired against the wrong tab after lunch. Teams paper over this with policy ("never query prod directly") that nobody follows, because sometimes you genuinely need to inspect live data during an incident.
The tooling gap is real: the safety features exist in bits and pieces (dry-run flags, read-only replicas, bastion audit logs) but none of them live where the risk actually is, which is the text box where someone types a statement at 2am. A client that puts the guardrail in the editor is a small product with a very clear pitch.
Stack sketch
- Shell: Tauri v2 — Rust backend, web frontend, small binary, no bundled Chromium the way Electron does it.
- Editor: Monaco with a SQL language service;
libpg_query(via thepg_query.rsbindings) to parse statements properly instead of regexing forDELETE. - Drivers:
sqlxfor Postgres and MySQL,rusqlitefor SQLite. Start with Postgres only. - Blast radius: rewrite the parsed statement into an equivalent
SELECT count(*)over the sameFROM/WHERE, run it in a read-only transaction, show the number. Fall back toEXPLAINrow estimates when the rewrite isn't safe. - Credentials: the
keyringcrate — OS keychain, never a plaintext JSON config next to the app. - Audit log: append-only JSONL in the app data directory, one line per executed statement with connection label, timestamp, statement text, and rows affected.
Scope for v1
In:
- Postgres connections with a per-connection risk level (
local,staging,production), set at creation and shown as a persistent banner. - Statement parsing that classifies each statement as read, write, or schema change.
- Row-count preview and a confirmation dialog for any write or schema change on a production connection.
- Autocommit disabled on production connections — an explicit Commit/Rollback bar appears after every write.
- Local JSONL audit log with an in-app viewer.
Out: query history sync, team features, schema diagramming, saved-query sharing, MySQL, anything cloud. The whole point of v1 is that it stores nothing off the machine.
Where it could go
The natural second step is turning the audit log into something a team can use. A small self-hosted collector that receives statement records from each developer's client gives you a real answer to "who touched the orders table last Tuesday" — which today usually means grepping bastion host shell history. That's the feature that makes it a paid team product rather than a free utility.
Past that, the risk classifier is reusable. The same parser that decides whether to show a confirmation can run in CI against migration files, flagging a migration that drops a column or rewrites a large table without a lock timeout. Selling one engine as both a desktop guardrail and a pipeline check is a cleaner story than either alone.
Watch out for
The count-rewrite is the hard part: subqueries, CTEs, and UPDATE ... FROM can all make the naive rewrite return a number that doesn't match what the statement will touch. Be conservative — when the rewrite isn't provably equivalent, say "estimate unavailable" rather than showing a confident wrong number, because a trusted-and-wrong preview is worse than no preview at all.