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.

1. Open your database
Section titled “1. Open your database”npx tablewalk postgres://reader@localhost/crm # PostgreSQLnpx tablewalk mysql://reader@localhost/crm # MySQL or MariaDBnpx tablewalk ./crm.sqlite # a SQLite filenpx tablewalk --demo # no database yet: a throwaway sampleYou 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.
2. Walk a record
Section titled “2. Walk a record”- Open a table and click a row. The record shows its fields.
- Click a reference, such as an invoice’s customer, to open that record.
- In the rail, pick a table that points here, such as the customer’s invoices, to see those rows.
- 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.
3. Ask a question in the query bar
Section titled “3. Ask a question in the query bar”Type into the bar above a table:
invoice total > 500 sort total descYou should now see only the matching rows, with the condition written into the address. The query language covers grouping, counting and following relationships.
4. Keep it read-only
Section titled “4. Keep it read-only”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.
5. Name your connections
Section titled “5. Name your connections”To keep several databases, or to keep a password out of your shell history, name them in a config file:
{ "connections": [ { "name": "crm", "url": "${DATABASE_URL}" }, { "name": "local", "url": "sqlite:./crm.sqlite" } ]}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.
If it fails
Section titled “If it fails”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.
- Query language: the bar’s full grammar, and MCP, the tools a coding agent gets.
- Quickstart: an App from your database: turn the same database into a workspace for a team.
- Performance: pool sizes and PgBouncer.