Skip to content

Quickstart: an App from your database

Turn a PostgreSQL database into a working App in five minutes, from the npm package alone.

You need Node 24 or newer and a database with a few related tables. To practice first, use a copy, or a role that can only read.

Terminal window
export DATABASE_URL=postgres://reader@localhost/crm
npx tablewalk --scaffold-app ./crm-app --name Sales

--scaffold-app reads the schema and writes a typed App project: app.ts, resources.ts, views.ts, dashboard.ts, pages/, the schema’s names in tablewalk-schema.d.ts, and a package.json and tsconfig.json, plus an .oxfmtrc.json and format / format:check scripts (oxfmt) so the project reads like the samples.

You should now see Drafted "Sales" in ./crm-app, with a count of views and record pages, and the next commands to run.

For a SQLite file, name the file instead: npx tablewalk ./crm.sqlite --scaffold-app ./crm-app --name Sales. That also writes a tablewalk.json naming the file, so the commands below need no DATABASE_URL.

No database yet? Write the tables in a schema.sql (create table …, with references between them) and make the SQLite file from it with Node’s own SQLite, then draft from the file as above:

Terminal window
node -e "new (require('node:sqlite').DatabaseSync)('crm.sqlite').exec(require('node:fs').readFileSync('schema.sql','utf8'))"

Keep schema.sql: later changes go through migrations that build it.

Terminal window
cd crm-app
npm install
npx tablewalk check --app .

check regenerates the schema types, typechecks the App and validates it against the database.

You should now see 3 of 3 steps passed. Warnings, such as an index a related list would use, are advice and do not fail the check.

Terminal window
npx tablewalk --app .

You should now see Sales: http://localhost:4111/. Open it:

  • the App in Lumen, the default look, set out in app.ts so it is yours to change, with a bar across the top;
  • an Overview dashboard: a count for each main table, how the work moves through its states as steps (or ranked bars), a trend by month and a donut of a second kind, and the newest rows. Over an empty database it opens on a first-run checklist instead: add the first record of each table;
  • a menu with a list for each table, the busiest first, then the records in a group and the lookups in a group that starts folded;
  • a record page for each table other tables point at, with its related rows in tabs;
  • references shown by name, such as an opportunity’s account, never by id.

Open views.ts, find a list, and remove a name from its show array. Save.

You should now see the page reload without that column. A save reloads the App; a change to who may sign in or what is granted needs a restart (reload and restart).

The draft only reads. To let a table be edited, add access: 'write' to its resource in resources.ts, and name the database in a config file with "writable": true; both are needed (resources and fields).

  • Cannot find module 'tablewalk/app' → run npm install in the App folder.
  • no database to check the App against → DATABASE_URL is not set in this shell; export it again, or pass the URL: npx tablewalk check --app . postgres://….
  • A typecheck error after a migration → run npx tablewalk check --app . again; it rewrites tablewalk-schema.d.ts from the database.