Skip to content

Run the demo

Five example applications ship with the source. They run side by side on one engine, on five subdomains, with no restart between them. They are the fastest way to see what a MatterData application looks like before you write one.

  • Go 1.27
  • a local clone of the repository
  • Node 22 and Bun 1.4, only if you also build this documentation site

From the repository root, create the five demo tenants:

Terminal window
make demo-tenants

The target writes one SQLite file per tenant under .local/tenants. Start the engine in a second terminal:

Terminal window
make engine

The engine now serves all five applications. *.localhost resolves to your own machine, so the addresses below work without a hosts-file entry.

Every demo account uses the password fixture-password-2026.

Application Address Accounts
Sports club club.localhost:8080 board@, trainer@, member@club.example
Local newspaper news.localhost:8080 chief@, editor@, author@, reader@news.example
Calendar calendar.localhost:8080 public; admin@calendar.example
School school.localhost:8080 head@school.example
Feature gallery showcase.localhost:8080 admin@, editor@, supervisor@, guest@showcase.example

Sign in at /matterdata/login. The calendar application opens its main page to anybody.

Each application has more than one account, because a role decides what a person sees. Open the same address as two different people and compare the result. A page that a role cannot open is not a refusal you can see: the link to it is absent, and the address answers 404.

The sports club is the broadest one. It has member records with photographs, a fee group that refuses to be deleted while members still use it, and a public event signup that closes when the event is full. The two refusals are written in different places. The fee group uses a hook in dsl/examples/sports-club/logic/, because it asks a question about other rows. The capacity check is a deny when rule on the signup form itself. Sign in as member@club.example to see a page bound to your own record, and as board@club.example to see the administrative pages that the member has no link to.

The local newspaper shows editorial states. An article moves from draft through review to published, and each move is a button that only appears when the actor may make that move from that state. The article body is Markdown, its word count is written by a hook, and its reading time is calculated from the word count. Published articles are public at /{slug}; a draft is readable only through a preview link.

The calendar is the smallest application and the only one whose main write is anonymous. A visitor picks the groups they care about and gets a calendar address to subscribe to. Open calendar.localhost:8080/kingshot_calendar/calendar/sub-calendar for a seeded subscription and its feed. The feed is the same query as the page, in the format a phone understands.

The school installs empty. It exists for its schema: 25 tables, an application-wide scope that puts every page in one school term, and grades marked sensitive. There is no demo data for it, so expect empty listings.

The feature gallery is not an application of anything. It is one page per language feature, and the address says which: /types/text, /regions/matrix, /access/row-filter, /time-zones/reader. Every page carries a note saying what it demonstrates and what to try. It uses every column type and every region type the language has, which the other four do not — each of them uses the part it needs.

The gallery is open without signing in, except for two kinds of page. The pages under Access show how a rule narrows what a login sees, so they need a login. Eight pages need a session for a reason that is itself a feature:

  • The sheet, the post form, the event form and the line-item form draw a ref control, which lists another table’s rows. A form open to visitors may not draw one.
  • The form, the list and the event pages over signups read a table the season scope filters. A visitor without a session has no season.

Navigation shows only what the current reader can open, so a signed-out visitor’s menu has no Access group. Sign in with the shared demo password shown above to see the rest. Any of the four gallery logins opens the pages that need a session. The Access pages differ by role.

Small menus show up to five links directly. Larger menus show a Menu control that opens the navigation groups. The panel uses columns on desktop and stacked sections on phones. Select a group to expand its links. Both layouts work without JavaScript. The engine counts only links that your account can open.

Open it as two different accounts to see authorization move. /access/sensitive shows a marked column to admin@ and hides it from supervisor@ on the same page. The four pages under /time-zones draw the same records in four different time zones.

For the shortest path, create one tenant and start the engine:

Terminal window
make engine-tenant
make engine

Then open club.localhost:8080/matterdata/login.

Run make demo-tenants again. The target deletes the five named tenants and recreates them, so keep nothing you care about in those databases.