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.
Prerequisites
Section titled “Prerequisites”| 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. |
Install the CLI
Section titled “Install the CLI”- 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, thenscoop 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 itsbin/on yourPATH. It is a fat jar plustesseraql/tesseraql.cmdlaunchers (JDK 25+ onPATH). - 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.
Create and run an app
Section titled “Create and run an app”tesseraql new myapp # scaffold into your own repo (config, a migration, routes, tests)cd myappdocker compose up -d # a local PostgreSQL (or point config at your own)tesseraql dev # runs the stack; your app at /<name>/, Studio at /_tesseraql/studiotesseraql scaffold crud --app . --table itemsFirst login
Section titled “First login”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):
printf 'change-me' > admin.pwtesseraql identity-schema --app . --admin-login admin --admin-password-file admin.pwThen 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.
Try it without a database
Section titled “Try it without a database”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:
tesseraql dev --embedded-db # ephemeral: a fresh DB, wiped on exittesseraql dev --embedded-db ./pgdata # persistent: data survives restartsIt 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:
tesseraql lint --app .tesseraql test --app . --report # also writes the documentation-portal overlaytesseraql coverage --app .tesseraql generate --app . # OpenAPI, htmx contract, docs spectesseraql 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.
curl -H "Authorization: Bearer $(tesseraql token --app . --role ADMIN)" \ http://localhost:8080/myapp/api/thingsThe Maven / CI path
Section titled “The Maven / CI path”tesseraql new also scaffolds a thin wrapper pom.xml and the Maven Wrapper, so CI needs only a
JDK:
./mvnw verify # lint + governance gate (no database)./mvnw tesseraql:migrate tesseraql:test \ -Dtesseraql.jdbcUrl=jdbc:postgresql://localhost:5432/myappThe framework artifacts resolve from GitHub Packages, which requires authentication even for
public reads. The scaffolded pom.xml declares no repository, so add both the repository and
a personal access token with read:packages to your ~/.m2/settings.xml (in CI, the workflow
GITHUB_TOKEN works the same way):
<settings> <activeProfiles><activeProfile>tesseraql</activeProfile></activeProfiles> <profiles> <profile> <id>tesseraql</id> <repositories> <repository> <id>github-tesseraql</id> <url>https://maven.pkg.github.com/ingcreators/tesseraql</url> </repository> </repositories> </profile> </profiles> <servers> <server> <id>github-tesseraql</id> <username>YOUR_GITHUB_USER</username> <password>ghp_your_token_with_read_packages</password> </server> </servers></settings>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.
Opt-in modules (drivers and codecs)
Section titled “Opt-in modules (drivers and codecs)”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:
tesseraql modules add io.tesseraql:tesseraql-pdf --app . # edits tesseraql.yml, writes modules.locktesseraql 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.
- your-first-app.md — the tutorial: an empty directory to a tested feature, step by step. Start here.
- troubleshooting.md — if the first run did not go to plan.
- reference-cli.md — every subcommand and flag.
- reference-config.md — every configuration key the framework reads.
- app-layout.md — the application directory and URL mapping.
- studio.md — the browser IDE
devjust opened. - deployment.md — container deployment.
- proxy.md — corporate proxy / internal mirror / air-gapped networks.