Skip to content

Getting started

You build an application on TesseraQL in your own repository — a directory of 2-way SQL, YAML routes, and templates (app-layout.md). You obtain the framework as installed tooling (the tesseraql CLI) and resolved Maven artifacts; you do not clone the framework repository to build an app. (Want to see a finished app before building one? The five-minute demo boots a seeded gallery app in one command.)

This documentation tracks the current development line. If a documented feature is missing from your installed CLI, it is newer than that release — check the release notes.

Item Required? Notes
JDK 25+ For the JVM channels Not needed on the host if you use the jpackage image (bundled JVM) or a container.
TesseraQL CLI Yes The only TesseraQL-specific tool. Studio and the pdf/excel codecs ride inside it.
A reachable PostgreSQL Yes — or none, with --embedded-db docker compose up -d (the scaffold ships a compose.yaml), point DB_USER/DB_PASSWORD (or config/application.yml) at an existing server, or run with an embedded database.
Docker Optional Convenience database and container image builds.
Maven No The CLI loop needs none; the Maven path uses the bundled ./mvnw (JDK only).
Node/npm No The UI is Hypermedia Components served from a WebJar; no JS build.
  • Homebrew (macOS / Linux)brew install ingcreators/tap/tesseraql. Installs the jar distribution on Homebrew’s OpenJDK; no separate JDK setup.
  • Scoop (Windows)scoop bucket add ingcreators https://github.com/ingcreators/scoop-bucket, then scoop install tesseraql. Ships the Windows app image with a bundled Java runtime; no JDK required.
  • Distribution archive — download tesseraql-cli-<version>-dist.zip (or .tar.gz) from a GitHub release, unpack it, and put its bin/ on your PATH. It is a fat jar plus tesseraql/tesseraql.cmd launchers (JDK 25+ on PATH).
  • Native image — the release / CI also builds a jpackage app image per OS (a launcher with a bundled JVM; no separate JDK needed).

Verify: tesseraql --version.

Terminal window
tesseraql new myapp # scaffold into your own repo (config, a migration, routes, tests)
cd myapp
docker compose up -d # a local PostgreSQL (or point config at your own)
tesseraql dev # runs the stack; your app at /<name>/, Studio at /_tesseraql/studio
tesseraql scaffold crud --app . --table items

Studio and the ops console sign in against the identity store, which is not seeded — while no users exist, dev says so and prints this step. Create the first administrator once (in a second terminal, with dev still running):

Terminal window
printf 'change-me' > admin.pw
tesseraql identity-schema --app . --admin-login admin --admin-password-file admin.pw

Then open http://localhost:8080/_tesseraql/studio and sign in with that login. The same command works under --embedded-db: dev leaves the running embedded database’s JDBC URL in work/embedded-db.jdbc, and the database-touching commands (identity-schema, migrate, scaffold crud, test, …) fall back to it under --app . whenever the configured database does not answer (announced as Using the running embedded database (work/embedded-db.jdbc)). To seed a database the app config does not reach — say a remote server — pass --jdbc-url explicitly; it always takes precedence. The full identity surface — roles, policies, SSO — is in authentication.md.

To run with no external database at all, add --embedded-db. The CLI starts an embedded PostgreSQL and points the app’s main datasource at it:

Terminal window
tesseraql dev --embedded-db # ephemeral: a fresh DB, wiped on exit
tesseraql dev --embedded-db ./pgdata # persistent: data survives restarts

It is a real postgres, so everything behaves exactly as it would against a server you run yourself — only the URL differs. The platform binary is downloaded on first use and cached (so the first run needs network); pass a directory to graduate the same data to a standalone server later by setting tesseraql.datasources.main.jdbcUrl. Embedded mode is single-process — for multiple app nodes, point them at a shared external PostgreSQL.

A persistent directory is pinned to the PostgreSQL version that initialized it, so a CLI upgrade never leaves your data unopenable; tesseraql embedded-db info ./pgdata shows where a directory stands and prints the upgrade procedure when one applies. Version pinning and cross-major upgrades are covered in deployment.md.

The interactive dev loop is all CLI-native:

Terminal window
tesseraql lint --app .
tesseraql test --app . --report # also writes the documentation-portal overlay
tesseraql coverage --app .
tesseraql generate --app . # OpenAPI, htmx contract, docs spec
tesseraql package --app . # build a .tqlapp under work/

migrate (apply/info/validate/repair), schema, governance, identity-schema, and verify round out the surface. Every subcommand calls the same engine as the matching Maven goal.

Prefer your own editor over Studio? tesseraql dev --watch watches the web/ tree — plus workflow/ and the shared definitions (decisions/, rules/, scope/, domains/) that bake into routes — and hot-reloads the moment you save: a route edit bounces that route, a workflow edit rebuilds its transition endpoints, a shared-definition edit rebuilds every route. The same instant loop as Studio’s Apply (jobs, consumers, and config/ changes still need a restart).

Smoke-testing a bearer-authenticated API? tesseraql token --app . --role ADMIN mints a development JWT signed with the app’s configured HS256 secret — roles land under the configured rolesClaim, --claim partner=P-100 adds custom claims (a JSON-looking value embeds structurally), --ttl 30m bounds it. Development only by construction: an app that verifies asymmetrically (publicKey/JWKS) has nothing this command could sign with.

Terminal window
curl -H "Authorization: Bearer $(tesseraql token --app . --role ADMIN)" \
http://localhost:8080/myapp/api/things

tesseraql new also scaffolds a thin wrapper pom.xml and the Maven Wrapper, so CI needs only a JDK:

Terminal window
./mvnw verify # lint + governance gate (no database)
./mvnw tesseraql:migrate tesseraql:test \
-Dtesseraql.jdbcUrl=jdbc:postgresql://localhost:5432/myapp

The framework artifacts are on Maven Central, so there is nothing to configure: the scaffolded pom.xml declares no repository because it needs none, and neither does your CI.

The BOM version-manages the opt-in JDBC drivers (ojdbc11, mssql-jdbc, mysql-connector-j), so a consumer declares bare coordinates. Behind a proxy or internal mirror, see proxy.md.

Base = the PostgreSQL driver + CSV codec. Everything else (Oracle/SQL Server/MySQL drivers, the pdf/excel/s3 modules) is declared in tesseraql.modules and resolved on demand:

Terminal window
tesseraql modules add io.tesseraql:tesseraql-pdf --app . # edits tesseraql.yml, writes modules.lock
tesseraql modules add com.oracle.database.jdbc:ojdbc11 --app .

modules.lock pins the exact resolved closure (committed, reproducible). dev resolves the declared set on start.

Non-PostgreSQL drivers are opt-in because their licenses differ: SQL Server (mssql-jdbc, MIT) is unencumbered; MySQL (mysql-connector-j, GPLv2 + FOSS Exception) and Oracle (ojdbc11, Oracle Free Use terms) are fetched at your explicit request from the vendor’s repository under the vendor’s terms — the framework never redistributes them. In CI, resolve modules once and bake the cache into your image so production hosts need no repository access.