What Termin is
Termin is a compiler and a reference runtime. You write an application description in constrained English in a .termin file. The compiler produces a .termin.pkg archive containing a compiled intermediate representation (IR — a JSON artifact the runtime consumes) and supporting artifacts. A conforming runtime reads the archive and serves a complete web application: a server-side-rendered web UI, a REST API for every declared content type, a WebSocket endpoint for real-time subscriptions, a managed database, access control enforced on every call, and a complete audit log of every modification.
The .termin file declares:
- Content — the records the application manages, their fields, and their types.
- Roles and scopes — who can perform which operations.
- State machines — the permitted states of each record and the transitions between them.
- Events — computations triggered by declared conditions.
- Channels — typed interfaces for data crossing a Boundary.
- Presentation — the pages and components rendered to each role.
A single .termin file expresses all of these. The compiler enforces consistency across them.
What Termin is not
- Not a general-purpose programming language. The expressive surface is deliberately narrow.
- Not a code generator for a framework you then extend by hand. The runtime consumes the compiled IR directly; there is no per-application scaffolding to edit.
- Not a database. The reference runtime uses SQLite; alternative runtimes can use whatever storage is appropriate.
- Not a UI toolkit. The presentation layer is declarative and rendered server-side. Rich client-side interactivity is outside its scope.
- Not a commercial product. Apache 2.0, no paid tier, no hosted offering. See /license.
A longer example
A fragment from the warehouse example that ships with the reference runtime:
Content called "products":
Each product has a SKU which is unique text, required
Each product has a name which is text, required
Each product has a category which is one of: "raw material", "finished good", "packaging"
Anyone with "inventory.read" can view products
Anyone with "inventory.write" can update products
Anyone with "inventory.admin" can create or delete products
State for products called "lifecycle":
A product starts as "draft"
A product can also be "active" or "discontinued"
A draft product can become active if the user has "inventory.write"
An active product can become discontinued if the user has "inventory.admin"
As a warehouse operator, I want to review inventory so that I can plan restocks:
Show a page called "Inventory"
Display a table of products with columns: SKU, name, category, state
Allow filtering by category, state
Allow searching by SKU, name
For each product, show actions:
"Activate" transitions to "active" if available, hide otherwise
"Discontinue" transitions to "discontinued" if available, hide otherwise
The full file is roughly 120 lines. It produces a working application with create, read, update, and delete operations (CRUD), access control, state transitions, a filterable and searchable inventory page, and the corresponding WebSocket subscription endpoints.
Is Termin a fit for what you want to build?
Termin is a good fit if your application is predominantly CRUD over structured records with declared roles, state transitions, and permissioned operations. Internal tools, line-of-business applications, and back-office systems match this shape. Applications that fit this shape cover most of what internal tools, line-of-business applications, and back-office systems do.
Termin is a poor fit for:
- Rich client-side interactivity beyond what its presentation primitives cover.
- Long-running or distributed transactions.
- Heavy numerical, graph, or signal processing.
- Applications whose core value is a bespoke UI.
Integration with external systems is expressed through Channels (typed interfaces) and Computes (pluggable providers). These extend what an application can do, but the provider itself is outside the Tier 1 guarantee boundary — see /guarantees.
How it differs from adjacent tools
- Rails, Django, and similar full-stack frameworks. General-purpose languages that can express any application, including insecure ones. Termin is deliberately less expressive — you trade expressiveness for properties the framework enforces on your behalf.
- Hasura. Exposes a database over GraphQL with declarative permissions. Termin's data-and-access layer has overlapping capability, but a
.terminfile also declares state machines, events, computations, and presentation in the same specification, with enforcement across all of them. - Supabase with PostgREST and row-level security. Conceptually closest on access control: declared policies are the only path to the data, enforced by the database. Termin extends the same philosophy to state transitions, computations, and the presentation layer, and provides one spec format rather than policies scattered across SQL and client configuration.
- Retool and similar internal-tool builders. Visual editors targeting end-user applications. Termin is a compiler; a visual editor is not part of the current project scope — see the roadmap for adjacent tooling considerations.
If your application fits what Termin can express, you get structural guarantees no general-purpose framework can provide. If it does not, Termin is the wrong tool. The fit diagnostic above exists so you can decide without installing.
For the full conceptual model — the primitives, how they compose, and why applications built from them are easier to reason about than applications written in a general-purpose language — see the Termin model.
Where the name comes from
The name layers four references, in rough order of weight:
- Lev Sergeyevich Termen (1896–1993), the Russian physicist and inventor known in the West as Leon Theremin. Termen invented the theremin in 1920 — one of the first electronic musical instruments, played without physical contact by moving the hands near two metal antennas to control pitch and volume. The theremin's eerie, vocal-like timbre, and its sonic descendants (electro-theremin, ondes Martenot, analog-synth leads tuned to similar effect), became the sound of mid-twentieth-century science fiction — a palette Star Trek has drawn on across its series.
- Determine — what a Termin application does: produce a determinate outcome from a specification.
- Deterministic — what a Termin compilation is: the same source, compiled by the same compiler version, produces the same IR.
- Terminus / Terminal — the boundary where the application meets the outside world.
Named after the inventor of a musical instrument that sounds the way secure-by-construction software tries to feel — unambiguous, precise, a little otherworldly — with the software-engineering overtones riding alongside.
Next
- Try it — install and run the warehouse example.
- See the guarantees — the three-tier model and its evidence.
- GitHub — compiler, reference runtime, issue tracker.