Introduction
Invariant is a TypeScript framework for building AI applications in which models can reason without owning business authority or execution state.
Models propose. Workflows constrain. The Runtime validates and commits.
Use Invariant when an AI-assisted process must combine semantic judgment with deterministic rules, external effects, human input, and inspectable execution history.
The Core Boundary
An Agent may interpret a request, and a .reason() node may answer a bounded semantic question. Neither directly becomes application truth. The Runtime accepts only actions allowed by the current workflow and commits valid transitions through the configured store.
text
User or application
│
▼
Model proposes an action ── optional
│
▼
Workflow constrains allowed paths
│
▼
Runtime validates and commits
│
▼
Application performs explicit effectsYour application remains authoritative for identity, permissions, business data, and provider-side idempotency.
The Building Blocks
| Building block | Responsibility | Read next |
|---|---|---|
| Workflow | Declares the permitted execution graph | Workflows & Graph Nodes |
| Step | Runs deterministic in-process logic | Execution Semantics |
| Capability | Marks an external side-effect boundary | Runtime Execution |
| Wait | Commits a suspension boundary for external input | Workflows: Wait |
| Reason | Delegates a bounded semantic decision with structured output | Workflows: Reason |
| Session | Carries application context and coordinates live workflow interaction | Sessions & Hydration |
| Projection | Selects the read-only facts visible to a consumer or model | Projections |
| RuntimeStore | Persists committed execution and Session facts | Storage & Deployment |
Agents are optional. Applications, API handlers, queues, and schedulers can start workflows directly.
What the Current Beta Guarantees
With a configured durable store, Invariant persists validated workflow transitions, ordered events, materialized state, Session context, and command intent. The initiating Session synchronously drains runnable commands while its handlers remain attached in the current process.
The current public Beta does not include automatic retry scheduling, timer workers, child workflow execution, or portable cross-process work continuation. A new process can restore an owned Session and reattach a registered run paused at .wait(), but it cannot publicly claim and redispatch an interrupted capability command. See the Recovery Contract Matrix for the exact boundary.
Invariant does not make external effects exactly once. Applications must provide stable provider request identifiers, and the external provider must enforce its own idempotency semantics.
Choose Your Path
- Build something now: Quick Start
- Understand the architecture: Mental Model
- Evaluate the tradeoffs: Why Invariant?
- Design a workflow: Workflows & Graph Nodes
- Operate durable storage: SQLite, PostgreSQL, and Self-Hosting
- Look up an API: TypeScript SDK Reference
- Start from working code: Examples & Showcases
For a first implementation, continue to the Quick Start.