Skip to content
ONIWC
iwc 0.1.0

.iwc language reference

.iwc files are strict JSON with a fixed shape per file type. There is no separate syntax to learn: what you learn is the vocabulary — which keys each file takes, what values they accept, and three conventions on top of JSON: expressions, bindings and file references. This page is the map; each section links to the full guide.

File structure

Every file is one JSON object. Its type comes from the file name, <your-name>.<type>.iwc, except the two fixed files app.iwc and package.iwc.

.ui.iwc
{
  "name": "About",
  "route": "/about",
  "layout": "main.layout.iwc",
  "title": "About us",
  "sections": [{ "type": "text", "variant": "h1", "content": "About us" }]
}

Rules that apply to every file:

RuleDetail
Strict JSONNo comments, no trailing commas, no duplicate keys, no NaN/Infinity. A file two parsers could read differently is refused
Closed shapeUnknown keys are errors. Keys starting with x- are kept and ignored — data for other tools ("x-designer": {…})
References by file name"layout": "main.layout.iwc", "resource": "product.schema.iwc", "api": "login.api.iwc". Base names are unique per type, wherever the file lives
No secretsLiteral credentials are compile errors; write {"env": "NAME"} and set the variable
PositionsEvery diagnostic names file:line:col

The full list of keys per file type is in file types; app.iwc is in app configuration.

File types

TypeRequired keysGuide
app.iwcnameApp configuration
package.iwcname, iwcApp configuration
.ui.iwcname, route, sectionsScreens & elements
.layout.iwcname, slotsLayouts
.component.iwcname, rootComponents
.schema.iwcname, fieldsDatabase
.api.iwcname, method, path — and exactly one of operation, action, workflowAPI development
.action.iwcname, stepsActions
.workflow.iwcname, resource, states, transitionsWorkflows
.event.iwcname (plus payload and handlers)Events
.job.iwcname, actionJobs
.state.iwcnameClient state
.security.iwcnameAuthentication
.service.iwcname, provider, methodsServices
.integration.iwcpackage, providerPackages
.widget.iwcname, scriptWidgets
.test.iwcname, casesDebugging & testing

Properties and data types

Values in .iwc files are JSON values. On top of them, IWC uses a few recurring formats, each validated by the compiler:

FormatExampleWhere
Identifiercart, order_itemsstore, mutation and field names: letters, digits and _, not starting with a digit
Name"Product page"name of files: letters, digits, space, -, _
Route/products/:slug, /docs/*screens (route), APIs (path, mounted under /api)
Duration500ms, 30s, 5m, 1h, 7dcaches, intervals, delays, session lifetimes
Ratio16/9image ratio
Rate"10/1m"security.rateLimit
Env reference{"env": "SHOP_DATABASE_URL"}any secret or environment-specific value
File reference"product.schema.iwc"any key that points at another file
Expression"=price * quantity"any string value that starts with = (below)

Field types (schemas)

Tables declare their columns as fields with a type:

typeStoresRules
stringshort textminLength, maxLength (default 10,000), pattern
textlong textmaxLength
integer, numbernumbersmin, max
booleantrue/false
email, urlvalidated text
passworda PBKDF2-SHA256 hashalways sensitive, never returned
date, datetimeYYYY-MM-DD, ISO 8601
enumone of values
relationthe id of a row in toonDelete: cascade, restrict, set null
jsonany JSON
filea file reference

Every field also takes required, unique, index, default, sensitive and description. See Database.

Field specs (requests and action input)

APIs (request.payload, request.query) and actions (input) validate incoming values with field specs:

field (in a .iwc file)
{ "type": "string", "required": true, "minLength": 2, "maxLength": 120, "trim": true }
KeyApplies to
typestring email url date datetime number integer boolean object array any
required, defaultall
minLength, maxLength, pattern, trimstrings
min, maxnumbers
enumstrings and numbers
minItems, maxItems, itemsarrays
fieldsobjects (nested specs)

Undeclared keys are always rejected. See Forms & validation.

Expressions

A string that starts with = is an expression, evaluated on the server:

element (in a .iwc file)
{ "type": "text", "content": "=concat(product.name, ' — ', format(product.price, 'currency', 'USD'))" }
Valuesnumbers, 'text' or "text", true, false, null
Namesproduct.price, item.name, tags[0], list.length
Operators+ - * / %, == != < <= > >=, `&&
Functionslists (sum avg min max count filter pluck first last sortBy join…), text (lower upper trim concat replace truncate…), values (coalesce if round number string…), dates (now date), display (format)

In scope: the current record's fields, component props, the page's named data, and always params, query, user, auth, page and app. Expressions cannot loop, assign, define functions or reach the network, and each evaluation has a budget. Inside actions, condition, items and string set.value are expressions without the =. Full reference: Expressions & page data.

Conditions

Conditional rendering uses visible, decided on the server — hidden elements are never sent to the browser:

element (in a .iwc file)
{
  "type": "column",
  "elements": [
    { "type": "link", "label": "Sign in", "target": "/login", "visible": { "auth": "signed-out" } },
    { "type": "link", "label": "Admin", "target": "/admin", "visible": { "roles": ["admin"] } },
    { "type": "badge", "content": "Low stock", "visible": "=product.stock < 5" }
  ]
}

In business logic, conditions are steps: require fails the action unless a condition holds, and if branches:

step (in a .iwc file)
{ "operation": "require", "condition": "product.stock >= input.quantity", "status": 409, "error": "=concat('Only ', product.stock, ' left')" }

Bindings

Bindings connect elements to data without expressions:

KeyBindsExample
data + itema container to a list of records; item repeats per record"data": {"source": "DATABASE.products"}
bindan element's text"bind": "name", "user.name", "params.slug", "state.cart.count"
bindsattributes"binds": {"source": "image", "alt": "name"}
fieldsa card's slots"fields": {"title": "name", "link": "/products/:slug"}
valuea form input's initial value"value": "item.title"
route patternslinks filled from the record"target": "/products/:slug"

Data sources are DATABASE.<table>, API.<name>, STATIC, USER and STATE.<store>.<list>. See Data binding.

Events and actions

There are three kinds of "something happens":

  1. UI actions on buttons and links: navigate, open, close, toggle, scroll, state, api, logout, share, install, notifications, sync, pay, tracking, native. Forms have submit.success (message, reset, navigate, redirect, mutation, reload). See the button element.
  2. Server actions: .action.iwc files run by APIs, other actions (callAction), events and jobs.
  3. Events and jobs: an action emits an event; the .event.iwc file's handlers run an action or queue a job. A .job.iwc runs an action in the background — queued with enqueue, or on a schedule.

Reusable definitions

To reuseUse
A piece of UIa component with props and slots
The frame around pagesa layout with slots
Business logican action, called by several APIs or by other actions (callAction)
Stylingtheme tokens in app.iwc and classes in styles/*.css
An external APIone .service.iwc or .integration.iwc, called from any action

Validation

Validation happens at three points:

  1. Compile time — iwc check validates every file against its schema and every reference. A project that compiles has no dangling references.
  2. Request time — every API validates its body, query and path parameters against its field specs and rejects undeclared fields with 422.
  3. Write time — schema field rules are enforced on every write, including writes from actions, so no path stores an invalid row.

Error handling

WhereHow
Data blocksempty (no records) and error (the source failed) elements
Formsfield errors under each input; the message above the button
API buttonsthe error message in place; success decides what happens on 2xx
Actionsa failing step stops the action, rolls back its transaction, and answers with its status and error
Pagesthe notFound screen in app.iwc for unknown routes and missing records
element (in a .iwc file)
{
  "type": "stack",
  "data": { "source": "API.products" },
  "item": { "type": "text", "bind": "name" },
  "empty": { "type": "text", "content": "No products yet." },
  "error": { "type": "text", "content": "Products could not be loaded." }
}

JSON Schemas

iwc schema --out <dir> writes one JSON Schema (draft 2020-12) per file type; iwc create puts them in .vscode/iwc-schemas/ and maps them in .vscode/settings.json, so VS Code completes and checks every key as you type. The same schemas drive the element reference.

Source: apps/marketing/content/docs/language.md