State & Expressions

Manage state and write expressions

State Types

Constela supports five state types:

number

Numeric values (integers and floating-point).

json
{
  "state": {
    "count": { "type": "number", "initial": 0 },
    "price": { "type": "number", "initial": 99.99 }
  }
}

string

Text values.

json
{
  "state": {
    "message": { "type": "string", "initial": "" },
    "username": { "type": "string", "initial": "Guest" }
  }
}

list

Arrays of values.

json
{
  "state": {
    "items": { "type": "list", "initial": [] },
    "todos": { 
      "type": "list", 
      "initial": [
        { "id": 1, "text": "Learn Constela", "done": false }
      ] 
    }
  }
}

boolean

True/false values for toggles and flags.

json
{
  "state": {
    "isOpen": { "type": "boolean", "initial": false },
    "darkMode": { "type": "boolean", "initial": true }
  }
}

object

Structured data with named properties.

json
{
  "state": {
    "user": {
      "type": "object",
      "initial": { "name": "", "email": "" }
    },
    "form": {
      "type": "object",
      "initial": { "title": "", "body": "", "tags": [] }
    }
  }
}

Expressions

Expressions are used throughout Constela to compute values dynamically. Every expression has an expr field that specifies its type.

lit - Literal Values

Static values that don't change.

json
{ "expr": "lit", "value": 42 }
{ "expr": "lit", "value": "Hello, World!" }
{ "expr": "lit", "value": true }
{ "expr": "lit", "value": null }

state - State References

Read the current value of a state field.

json
{ "expr": "state", "name": "count" }
{ "expr": "state", "name": "username" }

var - Variable References

Access loop variables or event payloads. Use path to access nested properties.

json
{ "expr": "var", "name": "item" }
{ "expr": "var", "name": "item", "path": "name" }
{ "expr": "var", "name": "item", "path": "user.email" }
{ "expr": "var", "name": "event", "path": "target.value" }

param - Component Parameters

Access parameters passed to a component.

json
{ "expr": "param", "name": "title" }
{ "expr": "param", "name": "disabled" }

bin - Binary Operations

Perform operations between two expressions.

json
{
  "expr": "bin",
  "op": "+",
  "left": { "expr": "state", "name": "count" },
  "right": { "expr": "lit", "value": 1 }
}

not - Logical Negation

Invert a boolean expression.

json
{
  "expr": "not",
  "operand": { "expr": "state", "name": "isHidden" }
}

cond - Conditional Values

Return different values based on a condition. Unlike the if node that controls what gets rendered, cond computes a value.

json
{
  "expr": "cond",
  "if": { "expr": "state", "name": "isDarkMode" },
  "then": { "expr": "lit", "value": "#1a1a1a" },
  "else": { "expr": "lit", "value": "#ffffff" }
}

Use cond for:

  • Dynamic text labels
  • Conditional CSS classes
  • Computed attribute values

get - Property Access

Access nested properties from expressions. Particularly useful with each loops over object arrays.

json
{
  "expr": "get",
  "base": { "expr": "var", "name": "item" },
  "path": "user.name"
}

Binary Operators

The bin expression supports these operators:

Arithmetic Operators

OperatorDescriptionExample
+Addition5 + 3 = 8
-Subtraction5 - 3 = 2
*Multiplication5 * 3 = 15
/Division6 / 3 = 2
json
{
  "expr": "bin",
  "op": "*",
  "left": { "expr": "state", "name": "quantity" },
  "right": { "expr": "state", "name": "price" }
}

Comparison Operators

OperatorDescription
==Equal
!=Not equal
<Less than
<=Less than or equal
>Greater than
>=Greater than or equal
json
{
  "expr": "bin",
  "op": ">=",
  "left": { "expr": "state", "name": "age" },
  "right": { "expr": "lit", "value": 18 }
}

Logical Operators

OperatorDescription
&&Logical AND
||Logical OR
json
{
  "expr": "bin",
  "op": "&&",
  "left": { "expr": "state", "name": "isLoggedIn" },
  "right": { "expr": "state", "name": "hasPermission" }
}

Expression Examples

Conditional Text

Display different text based on state using the if node:

json
{
  "kind": "if",
  "condition": {
    "expr": "bin",
    "op": ">",
    "left": { "expr": "state", "name": "count" },
    "right": { "expr": "lit", "value": 0 }
  },
  "then": {
    "kind": "text",
    "value": { "expr": "lit", "value": "Count is positive" }
  },
  "else": {
    "kind": "text",
    "value": { "expr": "lit", "value": "Count is zero or negative" }
  }
}

Using cond for Inline Conditional Values

When you need conditional text within an element (not conditional rendering), use the cond expression:

json
{
  "kind": "element",
  "tag": "span",
  "children": [
    {
      "kind": "text",
      "value": {
        "expr": "cond",
        "if": {
          "expr": "bin",
          "op": ">",
          "left": { "expr": "state", "name": "count" },
          "right": { "expr": "lit", "value": 0 }
        },
        "then": { "expr": "lit", "value": "Items available" },
        "else": { "expr": "lit", "value": "No items" }
      }
    }
  ]
}

Computed Values

Calculate a total from quantity and price:

json
{
  "kind": "text",
  "value": {
    "expr": "bin",
    "op": "*",
    "left": { "expr": "state", "name": "quantity" },
    "right": { "expr": "state", "name": "price" }
  }
}

Nested Object Access

Access nested properties from a list item using var with path:

json
{
  "kind": "each",
  "items": { "expr": "state", "name": "users" },
  "as": "user",
  "body": {
    "kind": "text",
    "value": { "expr": "var", "name": "user", "path": "profile.displayName" }
  }
}

Object Arrays with get

When iterating over arrays of objects, use get for explicit property access. Combined with cond, you can create rich displays:

json
{
  "kind": "each",
  "items": { "expr": "state", "name": "products" },
  "as": "product",
  "body": {
    "kind": "element",
    "tag": "div",
    "props": { "class": { "expr": "lit", "value": "product-card" } },
    "children": [
      {
        "kind": "element",
        "tag": "h3",
        "children": [
          {
            "kind": "text",
            "value": {
              "expr": "get",
              "base": { "expr": "var", "name": "product" },
              "path": "name"
            }
          }
        ]
      },
      {
        "kind": "text",
        "value": {
          "expr": "cond",
          "if": {
            "expr": "get",
            "base": { "expr": "var", "name": "product" },
            "path": "inStock"
          },
          "then": { "expr": "lit", "value": "In Stock" },
          "else": { "expr": "lit", "value": "Out of Stock" }
        }
      }
    ]
  }
}

Advanced Expressions

For more advanced use cases, Constela provides additional expression types. See the Expressions Reference for complete documentation:

  • route - Access route parameters, query strings, and current path
  • index - Dynamic array/object access with computed keys
  • import - Access static data from imported JSON files
  • data - Access build-time data sources (SSG)
  • ref - Reference DOM elements for JavaScript interop

Next Steps

Learn how to modify state with Actions & Events.