Skip to content

Quickstart: browse a database

Open a PostgreSQL, MySQL or SQLite database in the browser, follow its foreign keys, and keep it read-only.

You need Node 24 or newer. Run npx tablewalk --version to see which tablewalk you have. There is no build step and no config to write first.

A customer record in the database browser: its fields, the invoices that point at it, and a rail of every table that refers to it.

Terminal window
npx tablewalk postgres://reader@localhost/crm # PostgreSQL
npx tablewalk mysql://reader@localhost/crm # MySQL or MariaDB
npx tablewalk ./crm.sqlite # a SQLite file
npx tablewalk --demo # no database yet: a throwaway sample

You should now see Listening on http://localhost:4111 in the terminal. Open that address and you get a list of the database’s tables. Use --port to pick another port, or --open to have tablewalk open the browser for you.

  1. Open a table and click a row. The record shows its fields.
  2. Click a reference, such as an invoice’s customer, to open that record.
  3. In the rail, pick a table that points here, such as the customer’s invoices, to see those rows.
  4. Walk back (the browser’s Back works) to the view you came from.

You should now see the address change at each step: it names the connection, the table and the record (…/customer/~42). Copy it to share exactly what you are looking at.

Type into the bar above a table:

invoice total > 500 sort total desc

You should now see only the matching rows, with the condition written into the address. The query language covers grouping, counting and following relationships.

Every read runs in a read-only transaction. Writing is an opt-in for each connection ("writable": true in a config file), checked by the server in every route and tool that writes, not by the UI. The database role is the limit that always holds, so connect as a role that can only read:

CREATE ROLE tablewalk_reader LOGIN PASSWORD '…';
GRANT USAGE ON SCHEMA public TO tablewalk_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO tablewalk_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO tablewalk_reader;

You should now see no warning on startup. tablewalk prints one when the role it connects as could do more than read.

To keep several databases, or to keep a password out of your shell history, name them in a config file:

tablewalk.json
{
"connections": [
{ "name": "crm", "url": "${DATABASE_URL}" },
{ "name": "local", "url": "sqlite:./crm.sqlite" }
]
}
Terminal window
DATABASE_URL=postgres://reader@localhost/crm npx tablewalk --config ./tablewalk.json

${VAR} reads the environment, and an unset variable is an error. You should now see both connections offered in the browser, each opened only when you first use it.

  • Cannot find module 'pg' (or 'mysql2') → install the driver beside tablewalk: npm install pg.
  • The address answers nothing → another process holds port 4111; pass --port 4112.
  • A warning that the role “can do more” → connect as the read-only role above.