Packages

Overview of all Constela packages and their purposes

Overview

Constela is organized into several packages, each with a specific responsibility. This modular architecture allows you to use only what you need.

@constela/core

The foundational package containing type definitions, schema validation, and core utilities.

bash
npm install @constela/core

Key Exports

ExportDescription
ProgramTypeScript type for the root program structure
ViewNodeUnion type for all view node types
ExpressionUnion type for all expression types
ActionDefinitionType for action definitions
ActionStepUnion type for all step types
validateProgramFunction to validate a program against the schema
ProgramSchemaZod schema for runtime validation

Usage

typescript
import { Program, validateProgram } from '@constela/core';

const program: Program = {
  version: "1.0",
  state: { count: { type: "number", initial: 0 } },
  actions: [],
  view: { kind: "text", content: { expr: "state", name: "count" } }
};

const result = validateProgram(program);
if (result.success) {
  console.log('Valid program!');
} else {
  console.error('Validation errors:', result.errors);
}

@constela/compiler

The AST transformation and code generation package.

bash
npm install @constela/compiler

Key Exports

ExportDescription
compileMain compilation function
CompileOptionsConfiguration options for compilation
CompileResultResult containing generated code
transformAST transformation utilities

Usage

typescript
import { compile } from '@constela/compiler';
import type { Program } from '@constela/core';

const program: Program = { ... };

const result = compile(program, {
  target: 'esm',
  minify: true
});

console.log(result.code);

Compile Options

OptionTypeDefaultDescription
target"esm" | "cjs" | "iife""esm"Output module format
minifybooleanfalseMinify the output
sourcemapbooleanfalseGenerate source maps

@constela/runtime

The browser runtime for rendering and reactivity.

bash
npm install @constela/runtime

Key Exports

ExportDescription
createAppCreates an application instance
mountMounts the app to a DOM element
hydrateHydrates server-rendered HTML

Usage

typescript
import { createApp, mount } from '@constela/runtime';
import type { Program } from '@constela/core';

const program: Program = { ... };

const app = createApp(program);
mount(app, document.getElementById('app')!);

Runtime Features

  • Fine-grained reactivity: Only updates what changed
  • Event delegation: Efficient event handling
  • Memory efficient: Minimal DOM node creation
  • SSR compatible: Works with server-rendered HTML
  • Markdown rendering: GFM support with DOMPurify sanitization
  • Code highlighting: VS Code-quality syntax highlighting via Shiki

@constela/router

Client-side routing for multi-page Constela applications.

bash
npm install @constela/router

Key Exports

ExportDescription
createRouterCreates a router instance
RouteRoute configuration type
RouterOptionsRouter configuration options

Usage

typescript
import { createRouter } from '@constela/router';
import { createApp, mount } from '@constela/runtime';

const router = createRouter({
  routes: [
    { path: '/', program: homeProgram },
    { path: '/about', program: aboutProgram },
    { path: '/users/:id', program: userProgram }
  ]
});

router.onNavigate((program) => {
  const app = createApp(program);
  mount(app, document.getElementById('app')!);
});

router.start();

Route Parameters

Route parameters are automatically extracted and available in your program:

json
{
  "kind": "text",
  "value": { "expr": "param", "name": "id" }
}

@constela/server

Server-Side Rendering (SSR) package for any JavaScript server environment.

bash
npm install @constela/server

Key Exports

ExportDescription
renderToStringRenders a CompiledProgram to HTML string for SSR (async)

Usage

typescript
import { compile } from '@constela/compiler';
import { renderToString } from '@constela/server';

const myProgram = { /* ... */ };

async function generateHtml() {
  const result = compile(myProgram);
  if (!result.ok) throw new Error('Compile failed');

  const content = await renderToString(result.program);

  return `
    <!DOCTYPE html>
    <html>
      <body>
        <div id="app">${content}</div>
        <script type="module">
          import { createApp } from '@constela/runtime';
          import program from './program.js';
          createApp(program, document.getElementById('app'));
        </script>
      </body>
    </html>
  `;
}

Features

FeatureLibraryDescription
Markdown parsingmarkedGFM-compatible Markdown parser
Syntax highlightingshikiVS Code-quality code highlighting at build time
XSS protectionDOMPurifyHTML sanitization for security

RenderOptions

renderToString accepts an optional second parameter for customization:

typescript
interface RenderOptions {
  route?: {
    params?: Record<string, string>;
    query?: Record<string, string>;
    path?: string;
  };
  imports?: Record<string, unknown>;
  styles?: Record<string, StylePreset>;  // v4.1.0+
}

interface StylePreset {
  base: string;
  variants?: Record<string, Record<string, string>>;
  defaultVariants?: Record<string, string>;
}

SSR Style Evaluation (v4.1.0+)

Pass style presets via the styles option to evaluate style expressions on the server:

typescript
const html = await renderToString(result.program, {
  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">...</button>

Integration with Next.js

For Next.js projects, use @constela/server in Server Components:

typescript
// app/page.tsx (Server Component)
import { compile } from '@constela/compiler';
import { renderToString } from '@constela/server';
import { ConstelaClient } from './ConstelaClient';

const myProgram = { /* ... */ };

export default async function Page() {
  const result = compile(myProgram);
  if (!result.ok) throw new Error('Compile failed');

  const ssrHtml = await renderToString(result.program);

  return (
    <div>
      <h1>My App</h1>
      <ConstelaClient program={result.program} ssrHtml={ssrHtml} />
    </div>
  );
}
typescript
// ConstelaClient.tsx (Client Component)
'use client';
import { useEffect, useRef } from 'react';
import { createApp } from '@constela/runtime';
import type { CompiledProgram } from '@constela/compiler';

interface Props {
  program: CompiledProgram;
  ssrHtml: string;
}

export function ConstelaClient({ program, ssrHtml }: Props) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!ref.current) return;
    const app = createApp(program, ref.current);
    return () => app.destroy();
  }, [program]);

  return <div ref={ref} dangerouslySetInnerHTML={{ __html: ssrHtml }} />;
}

@constela/cli

Command-line tools for development and building.

bash
npm install -g @constela/cli
# or
npx constela

Commands

CommandDescription
constela build <file>Compile a program to JavaScript
constela dev <file>Start development server with hot reload
constela validate <file>Validate a program without building
constela validate --all <dir>Validate all JSON files in a directory
constela inspect <file>Visualize program structure
constela initInitialize a new Constela project

Build Command

bash
constela build app.json --output dist/app.js --minify

Options:

  • --output, -o: Output file path
  • --minify, -m: Minify output
  • --sourcemap, -s: Generate source map
  • --target, -t: Module format (esm, cjs, iife)
  • --json: Output result as JSON (for AI tool integration)
  • --watch, -w: Watch for changes and rebuild automatically
  • --verbose, -v: Show detailed progress (timing for each pass)
  • --debug: Show internal debug information

Dev Command

bash
constela dev app.json --port 3000

Options:

  • --port, -p: Dev server port (default: 3000)
  • --open, -o: Open browser automatically

Validate Command

bash
constela validate app.json
constela validate --all src/

Options:

  • --all: Validate all JSON files in the specified directory
  • --json: Output errors as structured JSON
  • --verbose, -v: Show detailed validation info

Validates the program and reports any errors without generating output. Error messages include "Did you mean?" suggestions for typos:

text
Error [UNDEFINED_STATE] at /view/children/0/value/name

  Undefined state reference: 'count'

  Did you mean 'counter'?

Inspect Command

bash
constela inspect app.json
constela inspect --state --json app.json

Options:

  • --json: Output as JSON
  • --state: Show only state section
  • --actions: Show only actions section
  • --verbose, -v: Show all details

Shows program structure including state fields, actions, components, and dependencies.

@constela/builder

For those who prefer TypeScript over writing JSON directly, we've added a Builder API.

bash
npm install @constela/builder

Example

typescript
import {
  createProgram, numberField, action, increment,
  button, text, state, onClick
} from '@constela/builder';

const counter = createProgram({
  state: { count: numberField(0) },
  actions: [action('increment', [increment('count')])],
  view: button({ onClick: onClick('increment') }, [text(state('count'))])
});

40+ Builder Functions

Covers all DSL elements:

CategoryFunctions
Expressionlit, state, variable, bin, cond, get, add, eq, and, or, etc.
StatenumberField, stringField, booleanField, listField, objectField
Actionaction, set, update, increment, push, fetch, navigate, etc.
Viewelement, div, button, text, ifNode, each, component, slot
EventonClick, onInput, onChange, onSubmit

Same Benefits as JSON

Even when written in TypeScript, it gets converted to JSON. That means:

  • Compile-time error detection - Errors if you reference undefined state or actions
  • "Did you mean?" suggestions - Typos get corrected with helpful hints
  • Structured error output - AI integration with --json flag works seamlessly

@constela/start

Meta-framework for building full-stack Constela applications with file-based routing, SSR, SSG, and edge runtime support.

bash
npm install @constela/start

Key Exports

ExportDescription
defineConfigConfiguration function for constela.config.ts
APIContextType for API route handlers
MiddlewareHandlerType for middleware functions
GetStaticPathsType for SSG path generation
RouteParamsType for route parameter access

Usage

typescript
// src/routes/index.ts
import type { Program } from '@constela/core';

export default {
  version: '1.0',
  state: { count: { type: 'number', initial: 0 } },
  actions: [
    { name: 'increment', steps: [{ do: 'update', target: 'count', operation: 'increment' }] }
  ],
  view: {
    kind: 'element',
    tag: 'div',
    children: [
      { kind: 'text', value: { expr: 'state', name: 'count' } },
      {
        kind: 'element',
        tag: 'button',
        props: { onClick: { event: 'click', action: 'increment' } },
        children: [{ kind: 'text', value: { expr: 'lit', value: '+1' } }]
      }
    ]
  }
} satisfies Program;

CLI Commands

CommandDescription
constela-start devStart development server with HMR
constela-start buildBuild for production
constela-start startStart production server

Features

FeatureDescription
File-based routingRoutes generated from src/routes/ directory
SSRServer-side rendering with @constela/server
SSGStatic site generation with getStaticPaths
API RoutesGET/POST/PUT/DELETE/PATCH endpoints
MiddlewareKoa/Hono-style next() pattern
Edge RuntimeCloudflare Workers, Vercel Edge, Deno

Package Dependencies

text
@constela/cli
  ├── @constela/core
  ├── @constela/compiler
  └── @constela/runtime

@constela/start
  ├── @constela/core
  ├── @constela/compiler
  ├── @constela/runtime
  └── @constela/server

@constela/server
  └── @constela/compiler (peer)

@constela/router
  └── @constela/runtime
      └── @constela/core

@constela/compiler
  └── @constela/core

Version Compatibility

All packages follow semantic versioning and are released together. Always use the same version across all Constela packages in your project.

json
{
  "dependencies": {
    "@constela/core": "^1.0.0",
    "@constela/compiler": "^1.0.0",
    "@constela/runtime": "^1.0.0"
  }
}