irgen mirrors compiler architecture: DSL captures intent, IR encodes structure, lowering resolves policy into TargetIR, and emitters serialize output. irgen can generate frontend apps, backend targets, or both. Each stage has clear responsibility and does not leak into others.
Deterministic
Same DSL plus policy produces the same output.
Policy-Driven
All decisions happen in lowering, never in emitters.
Multi-Target
Backend, Frontend, Electron, and Static Site from one IR.
1graph TD
2 DSL[DSL] --> Decl[DeclIR]
3 Decl --> Domain[DomainIR]
4 Domain --> Lowering[Lowering]
5 Lowering --> Target[TargetIR]
6 Target --> BE[Backend Emitter]
7 Target --> FE[Frontend Emitter]
8 Target --> SS[Static Site Emitter]
9 BE --> BE_OUT[Backend API]
10 FE --> FE_OUT[Frontend Webapp]
11 SS --> SS_OUT[Static Docs]
12 subgraph "Target Example: Frontend"
13 FE_OUT --> Runtime[Headless Runtime]
14 FE_OUT --> Components[UI Components]
15 Components -->|Hooks| Runtime
16 endWhat is irgen?
irgen is a compiler-style code generation framework built around an Intermediate Representation (IR). It translates system intent to IR, then to TargetIR, and finally to emitted code.
Problems irgen Solves
Modern projects often target backend, frontend, desktop, and static output, each with different dependencies and conventions. irgen centralizes intent into IR to reduce boilerplate and keep architecture consistent across all targets.
Compiler-Style Pipeline
irgen follows a rigorous pipeline: DSL -> DeclIR -> DomainIR -> TargetIR -> Emitter. This separation ensures that high-level intent is never mixed with target-specific implementation details or policy decisions.
IR as Contract
Intermediate Representation (IR) is the single source of truth. It represents intent, not implementation. Emitters never reinterpret policy; they simply serialize the deterministic TargetIR produced by the lowering stage.
Target Separation
Backend and frontend targets remain strictly independent. Each has its own lowering rules and emitters. Enabling one does not implicitly affect the other, keeping the architecture modular and scalable.
Operation vs Action
For contributors and extension authors, the layer distinction is key: Operation is the backend-facing contract (Path, Method, Params). Action is the frontend-facing binding (Hooks, Loading State, Success/Error).
Lowering as Decision Point
Lowering reads policy, resolves constraints, and produces TargetIR that is already final. Parameters like database providers, rendering modes, or auth strategies are resolved here, keeping emitters pure and execution-only.
Target Capability: Operation-Oriented Frontend
Within the Frontend target, irgen leverages an Operation-Oriented architecture. It treats interactions as discrete operations, allowing the generated UI to connect to any backend via a standardized Headless Runtime.
Headless Client Runtime
A core part of the generated Frontend target is the Headless Runtime. This auto-generated library (lib/runtime.ts) manages data fetching and authentication, serving as the bridge between declarative UI and external APIs.