# I turned the psql commands I keep forgetting into buttons

> Source: <https://dev.to/hitoshi1964/i-turned-the-psql-commands-i-keep-forgetting-into-buttons-d26>
> Published: 2026-06-15 12:34:20+00:00

You know the command exists. You've run it a dozen times. But every single time you need to see what's *actually* running on your database, you end up typing some variant of:

```
SELECT pid, state, query, wait_event_type
FROM pg_stat_activity
WHERE state != 'idle' AND pid != pg_backend_pid();
```

…and then googling `pg_stat_activity columns`

halfway through because you forgot whether it's `wait_event`

or `wait_event_type`

.

I got tired of that. So I built ** cli2ui** — a small web UI that turns the database CLI commands you keep half-remembering into buttons.

```
psql -c "SELECT * FROM pg_stat_activity"   →  one "running queries" button
pg_dump -t users mydb                       →  one "back up this table" button
SELECT pg_terminate_backend(pid)            →  one "kill this process" button
```

No AI. No SaaS. No magic. It runs **on your machine, right next to your database**, and your connection credentials never leave your network.

It's built for **app developers and solo developers** — not DBAs. The pitch is "you're looking at your tables 3 minutes after deciding to": `docker compose up`

, connect, done. No install marathon, no connection-wizard maze, no digging through nested trees.

A few of the things it puts one click away (PostgreSQL today):

`\d table`

), and a row preview.`SET TRANSACTION READ ONLY`

transaction (so the `statement_timeout`

and a 1000-row cap. Write mode is opt-in and takes a whole-database safety snapshot `pg_stat_activity`

and the blocking tree from `pg_locks`

+ `pg_blocking_pids`

, with one-click cancel / kill.`wal_level`

/ `max_wal_senders`

), connected standbys, slot create/drop, and a copy-paste `pg_basebackup`

command.`pg_settings`

+ `ALTER SYSTEM SET`

+ `pg_reload_conf()`

, with reload-vs-restart badges.`pg_dump`

snapshots before every destructive change, restore of an uploaded dump streamed to the client tool (not buffered in memory).The UI ships in **English and Japanese** with a header toggle.

cli2ui has **no authentication layer**. That sounds reckless until you look at the threat model: it's a trusted local tool sitting next to your database, not a multi-tenant service on the internet. No accounts, no outbound calls, no AI. Your DB credentials stay on your machine.

The moment you'd hold someone's database connection info on a server, the liability-and-encryption story swallows the whole project. Staying local keeps it honest — and the README is very loud about *"don't expose this to an untrusted network."*

Being local doesn't mean being careless:

`psycopg2.sql.Identifier`

; the few raw-SQL spots (e.g. index access method, column type) go through fixed allow-lists.`autocommit=False`

and always `ROLLBACK`

.`localhost`

and drop your database), and `X-Frame-Options: DENY`

stops clickjacking the destructive buttons.`node_modules`

. Panels are htmx partials; the page swaps `innerHTML`

and that's the whole interaction model.That last bit is the thing I'm happiest about: adding a feature is small and mechanical, which is why the PostgreSQL coverage got deep instead of wide.

```
git clone https://github.com/MR-TABATA/cli2ui
cd cli2ui
docker compose up
# then open http://localhost:8000
```

The connection form is pre-filled to point at a bundled sample database — hit **Connect** and you're looking at its tables. To point at your own PostgreSQL, change the form fields. (Connecting to a database in *another* container trips everyone up — there's a [whole networking guide](https://github.com/MR-TABATA/cli2ui/blob/main/README.NETWORKING.md) for that.)

It's **MIT-licensed** and the code is on [GitHub](https://github.com/MR-TABATA/cli2ui). The landing page is at ** cli2ui.com**.

If you've ever rage-googled `pg_stat_replication`

columns, I'd love your feedback — especially on what command you reach for most that *should* be a button.
