Constela: Built-in a11y Checks, Plugin System & CSS Transitions

Published: (February 8, 2026 at 02:30 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

What’s New in Constela

Constela is a JSON‑based declarative UI framework — you write your entire UI in JSON, and the compiler + runtime handles the rest. We’re shipping three features that make Constela apps more accessible, extensible, and polished.

1. Compile‑Time Accessibility Checks

Accessibility shouldn’t be an afterthought. Constela now checks your JSON programs for common a11y issues at compile time and reports them as warnings.

Built‑in Rules

RuleWhat it catches
IMG_NO_ALTImages without alt text
BUTTON_NO_LABELButtons with no text or aria-label
ANCHOR_NO_LABELLinks with no text or aria-label
INPUT_NO_LABELInputs without a label
HEADING_SKIPSkipped heading levels (e.g., h1 → h3)
POSITIVE_TABINDEXPositive tabindex values
DUPLICATE_IDDuplicate id attributes

These are warnings, not errors — your code still compiles, so you can adopt them gradually.

const result = compile(myProgram);
if (result.ok && result.warnings?.length) {
  result.warnings.forEach(w => console.warn(`[${w.code}] ${w.message}`));
}

2. Plugin System

Want to use custom functions in your JSON DSL? Now you can.

Define a Plugin

import type { ConstelaPlugin } from '@constela/core';

const myPlugin: ConstelaPlugin = {
  name: 'my-analytics',
  version: '1.0.0',
  globalFunctions: {
    trackEvent: (category: string, action: string) => { /* ... */ },
    formatCurrency: (amount: number) => `$${amount.toFixed(2)}`,
  },
};

export default myPlugin;

Register It

Add to constela.config.json:

{
  "plugins": ["my-analytics", "./src/plugins/local-plugin"]
}

That’s it — your functions are now available in the DSL.

Safety features

  • Atomic registration (all‑or‑nothing)
  • Prototype‑pollution protection (__proto__, constructor, prototype blocked)
  • Works in both client and server rendering

3. CSS Class‑Based Transitions

Conditional rendering (if nodes) now supports smooth enter/exit animations.

Example JSON

{
  "kind": "if",
  "condition": { "expr": "state", "name": "showToast" },
  "then": {
    "kind": "element",
    "tag": "div",
    "children": [
      { "kind": "text", "value": { "expr": "lit", "value": "Saved!" } }
    ]
  },
  "transition": {
    "enter": "slide-in",
    "enterActive": "slide-in-active",
    "exit": "slide-out",
    "exitActive": "slide-out-active",
    "duration": 250
  }
}

Corresponding CSS

.slide-in { transform: translateY(-20px); opacity: 0; }
.slide-in-active { transition: all 250ms ease; transform: translateY(0); opacity: 1; }
.slide-out { transform: translateY(0); opacity: 1; }
.slide-out-active { transition: all 250ms ease; transform: translateY(-20px); opacity: 0; }

The runtime handles:

  • Enter flow: create element → apply enter → next frame: swap to enterActive → cleanup
  • Exit flow: apply exit → next frame: swap to exitActive → remove element
  • Fast toggling: cancels in‑progress animations gracefully
  • SSR: transitions are ignored server‑side (no changes needed)

Try It Out

npm install @constela/core @constela/compiler @constela/runtime @constela/start
npx constela dev

Check out the Language Specification for the full DSL reference, or browse the Examples to see these features in action.

0 views
Back to Blog

Related posts

Read more »

Build a Multimedia Player

Author’s Note: My ADHD was in full tilt this morning, which is why I mention in this post that I plan to revisit this lab at a later date to expand the accessib...