Skip to content

App Builder

Build custom applications with a visual editor and JSON definitions

App Builder lets you create custom web applications using a visual editor or JSON definitions. Applications consist of pages with layouts, components, and actions - all without writing frontend code.

Key capabilities:

  • Visual drag-and-drop editor
  • 20+ pre-built components (tables, forms, charts, etc.)
  • Expression syntax for dynamic content ({{ user.name }})
  • Workflow integration for backend logic
  • Role-based permissions
  • Embeddable in external sites
Define pages → Add components → Configure actions → Publish

Application lifecycle:

  1. Create application in editor
  2. Add pages with layouts (rows, columns, grids)
  3. Drop components and configure properties
  4. Connect to workflows and data sources
  5. Set up permissions
  6. Publish and share

Pages are the screens of your application. Each page has:

  • Path: URL route (e.g., /dashboard, /users/:id)
  • Layout: Component arrangement (rows, columns, grids)
  • Data Sources: Data loaded when page mounts
  • Launch Workflow: Optional workflow to run on page load
  • Permissions: Who can access the page

Layouts arrange components using flexbox or grid:

TypeDescriptionUse Case
rowHorizontal flex containerToolbars, button groups
columnVertical flex containerForms, card stacks
gridCSS grid with columnsDashboards, galleries

Layouts can be nested for complex arrangements.

Components are the building blocks:

  • Display: Heading, Text, Image, Badge, Progress, StatCard
  • Data: DataTable, Tabs, FileViewer
  • Input: TextInput, NumberInput, Select, Checkbox
  • Interactive: Button, Modal, Card
  • Forms: FormEmbed, FormGroup

See Components Reference for full details.

Dynamic content uses {{ expression }} syntax:

// Access user data
{{ user.name }}
{{ user.email }}
// Access page variables
{{ variables.selectedId }}
// Access form field values
{{ field.customerName }}
// Access workflow results
{{ workflow.result.orderId }}
// Comparisons and logic
{{ user.role == 'admin' }}
{{ variables.count > 0 && user.isActive }}

See Expressions Reference for full syntax.

Components trigger actions on user interaction:

  • navigate: Go to another page
  • workflow: Execute a backend workflow
  • set-variable: Update a page variable
  • refresh-table: Reload a data source
  • submit: Submit form fields to a workflow

See Actions Reference for configuration.

A simple dashboard with a data table:

{
"id": "dashboard-app",
"name": "Customer Dashboard",
"version": "1.0.0",
"pages": [
{
"id": "home",
"title": "Customers",
"path": "/",
"dataSources": [
{
"id": "customers",
"type": "workflow",
"workflowId": "get_customers"
}
],
"layout": {
"type": "column",
"gap": 16,
"children": [
{
"id": "title",
"type": "heading",
"props": {
"text": "Customer List",
"level": 1
}
},
{
"id": "table",
"type": "data-table",
"props": {
"dataSource": "customers",
"columns": [
{ "key": "name", "header": "Name" },
{ "key": "email", "header": "Email" },
{ "key": "status", "header": "Status", "type": "badge" }
],
"rowActions": [
{
"label": "View",
"onClick": {
"type": "navigate",
"navigateTo": "/customers/{{ row.id }}"
}
}
]
}
}
]
}
}
]
}

Control who can access the entire app:

{
"permissions": {
"public": false,
"defaultLevel": "none",
"rules": [
{ "role": "admin", "level": "admin" },
{ "role": "*", "level": "view" }
]
}
}

Restrict specific pages:

{
"permission": {
"allowedRoles": ["admin", "manager"],
"redirectTo": "/access-denied"
}
}

Hide components with expressions:

{
"type": "button",
"visible": "{{ user.role == 'admin' }}",
"props": { "label": "Delete All" }
}
Page Load
Run Launch Workflow (optional)
Load Data Sources
Render Layout with Expression Context
User Interaction → Trigger Action
Execute Workflow / Navigate / Update Variable
Re-render with Updated Context

Components receive context for expression evaluation:

VariableDescription
userCurrent user (id, name, email, role)
variablesPage-level mutable state
dataLoaded data sources by ID
fieldForm input values
workflowLast workflow execution result
rowCurrent row (in table actions only)
  1. Keep pages focused: One purpose per page
  2. Use data sources: Don’t hardcode data in components
  3. Validate in workflows: Backend validation is required
  4. Test permissions: Verify access controls work correctly
  5. Use variables sparingly: Complex state should live in workflows