What is Constela?
Constela is a compiler-first UI framework where you describe UI behavior in a constrained JSON DSL. Instead of writing JavaScript/JSX, you write declarative JSON that gets validated, analyzed, and compiled into minimal runtime code.
New Feature in @constela/server v4.1.0
The renderToString function now accepts a styles option, allowing style presets to be passed for evaluation during server-side rendering. Style expressions are evaluated and output as CSS class strings.
How It Works
1. Define Style Presets
Constela's style system is similar to Tailwind Variants or CVA:
{
"styles": {
"button": {
"base": "px-4 py-2 rounded font-medium transition-colors",
"variants": {
"variant": {
"primary": "bg-blue-500 text-white hover:bg-blue-600",
"secondary": "bg-gray-200 text-gray-800 hover:bg-gray-300",
"danger": "bg-red-500 text-white hover:bg-red-600"
},
"size": {
"sm": "text-sm px-3 py-1",
"md": "text-base px-4 py-2",
"lg": "text-lg px-6 py-3"
}
},
"defaultVariants": {
"variant": "primary",
"size": "md"
}
}
}
}
2. Use Style Expressions in Views
{
"kind": "element",
"tag": "button",
"props": {
"className": {
"expr": "style",
"name": "button",
"variants": {
"variant": { "expr": "state", "name": "currentVariant" }
}
}
}
}
3. Pass Styles to SSR
import { renderToString } from '@constela/server';
const html = await renderToString(compiledProgram, {
styles: {
button: {
base: 'px-4 py-2 rounded',
variants: {
variant: {
primary: 'bg-blue-500 text-white',
secondary: 'bg-gray-200 text-gray-800',
},
},
defaultVariants: { variant: 'primary' },
},
},
});
Output
<button class="px-4 py-2 rounded bg-blue-500 text-white">Click me</button>
API Reference
interface RenderOptions {
route?: {
params?: Record<string, string>;
query?: Record<string, string>;
path?: string;
};
imports?: Record<string, unknown>;
styles?: Record<string, StylePreset>; // Added in v4.1.0
}
interface StylePreset {
base: string;
variants?: Record<string, Record<string, string>>;
defaultVariants?: Record<string, string>;
}
Why Constela?
| Constela | React/Next.js | |
|---|---|---|
| UI authoring | JSON DSL | JavaScript/JSX |
| Execution | Compiler-driven | Runtime-driven |
| State updates | Declarative actions | Arbitrary JS |
| Errors | Structured with JSON Pointer | Runtime exceptions |
Constela is optimized for:
- AI-generated UI
- Deterministic behavior
- Inspectable state transitions
Get Started
npm install @constela/start
mkdir -p src/routes
Create src/routes/index.json:
{
"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" } }]
}
}
Run:
npx constela dev
Summary
With @constela/server v4.1.0, style expressions are now evaluated during SSR. Just pass your style presets to the styles option in renderToString, and your styles will be applied on the server just like on the client.
If you're interested in Constela, give it a try. We welcome your feedback and issues on GitHub.
Links
@constela/server v4.1.0 is available now. Upgrade with npm install @constela/server@latest
Top comments (0)