AI-assisted coding is becoming normal.
More and more UI code is generated, not carefully handwritten.
After experimenting with this workflow for a while, I kept running into the same problem:
Most UI bugs are still discovered at runtime.
That’s fine when humans write code incrementally and manually test it.
It becomes much harder when large chunks of UI are generated at once.
This is the motivation behind Constela.
What is Constela?
Constela is a compiler-first UI language designed for vibecoding.
Instead of writing UI logic in JavaScript or JSX, you describe UI behavior using a constrained JSON-based DSL.
That DSL is then validated, analyzed, and compiled before it ever runs.
JavaScript is still the execution target —
but it’s no longer the authoring language for UI.
Why a UI language instead of another framework?
Traditional JavaScript UI frameworks are extremely powerful, but they share a core assumption:
UI logic is written by humans, and validated through execution.
Constela explores a different assumption:
UI logic is increasingly generated, and should be verifiable before execution.
So instead of arbitrary JavaScript, Constela deliberately limits what you can express:
- No user-defined functions
- No arbitrary expressions
- No runtime mutation outside declared actions
In exchange, you get:
- Compile-time validation
- Deterministic state transitions
- Structured, inspectable errors
Mental Model
| React / Next.js | Constela | |
|---|---|---|
| UI authoring | JavaScript / JSX | JSON DSL |
| Execution model | Runtime-driven | Compiler-driven |
| State updates | Arbitrary JS | Declarative actions |
| Errors | Runtime exceptions | Structured compile-time errors |
If React treats UI as code,
Constela treats UI as verifiable data.
A Small Example
Here’s a minimal counter app in Constela:
import { compile } from '@constela/compiler';
import { createApp } from '@constela/runtime';
const program = {
version: "1.0",
state: {
count: { type: "number", initial: 0 }
},
actions: [
{
name: "increment",
steps: [{ do: "update", target: "count", operation: "increment" }]
}
],
view: {
kind: "element",
tag: "button",
props: {
onClick: { event: "click", action: "increment" }
},
children: [
{ kind: "text", value: { expr: "state", name: "count" } }
]
}
};
const result = compile(program);
if (result.ok) {
createApp(result.program, document.getElementById("app"));
}
There are no functions here — only declared state, named actions, and explicit structure.
What makes this AI-friendly?
Constela’s DSL is:
- Finite and enumerable LLMs can learn the entire surface area.
- Schema-validated Invalid structure fails immediately.
- Statically analyzable Missing state, invalid updates, or broken references are caught at compile time.
- Deterministic The same input always produces the same behavior.
This makes it well-suited for workflows where UI is produced, validated, and refined by machines.
Components and Routing
Constela supports reusable components with typed params and slots, all defined in the same DSL.
Routing is provided via a separate package (@constela/router) and intentionally kept outside the core language.
The DSL stays focused on UI structure; routing is an application-level concern.
What Constela focuses on
Constela focuses on a compiler-driven approach to UI authoring.
UI behavior is described as structured data, validated and analyzed before execution,
with the goal of making correctness explicit and machine-checkable.
This design prioritizes:
- static guarantees over runtime flexibility
- deterministic behavior over ad-hoc logic
- analyzability over unrestricted expressiveness
Who might find this interesting?
- Developers experimenting with AI-generated frontends
- People interested in compiler-driven UI architectures
- Anyone curious about treating UI as data instead of code
Project Links
Feedback welcome
Constela is still early-stage.
I’m explicitly looking for critical feedback, especially around:
- Where this model breaks down
- What it makes harder than existing frameworks
- Whether this makes sense at all outside experiments
If you think this is the wrong direction, I’d genuinely like to know why.
Top comments (0)