.ifml
Interaction flow
Views, navigation and CLI commands
No in-tree backend — the artifact is validated and committed, not consumed.
Interaction flows over a composed pattern library: views, containers, components, events, navigation, and the declaration-backed control/route manifest.
Why it exists
What .ifml is for
An .ifml file describes the interaction model: views and containers, the components inside them, the events those components raise, and where navigation goes — semantically aligned with OMG IFML 1.0, in a C-like, expression-heavy syntax instead of XML.
The domain defines the data; the flow defines what the user sees and does with it. Entity and field references are checked against the imported .mox domains and .actor policies, the reference pattern library is composed with use, and a declaration-backed control and route manifest is derived after checking, so every route target in it exists by construction.
Vocabulary
What it models
The concepts .ifml declares, and what each one means to the compiler.
- view
- A top-level interaction unit, with
paramsand a label; containers nest inside it. - component
list,table,details,formand the chart kinds, withdata:bound to a domain type.- fields / column
- A component’s bindings (
fields: [ticketNo, title]), and computed columns such ascolumn "Refund" -> expr refundCents / 100. - on <event> -> …
- A component event whose handler navigates, or invokes a declared action. An
ifguard may filter it. - navigate(…)
- A target view or container, with parameter bindings.
- action
- A declared action with a domain
target:. The declaration is what makes an event’s action reference resolve. - use
- Instantiates a module from the reference pattern library with input bindings.
- command
- A CLI command declaration with typed arguments and options: the binary’s command surface.
- manifest
- The control and route manifest, derived after checking — never parsed, and declaration-backed by construction.
Source
A working example
Quoted from the example this page's artifact was compiled from — not a snippet written for the website.
Lines 12–29 of examples/support/support.ifml, reproduced byte for byte, read from the file at build time:
view "Inbox" {
params { tickets: Ticket, folders: Ticket };
label "Support Inbox";
landmark: true;
use "Inbox" as inbox { messages: tickets; folders: folders; };
component "escalations" {
type: list;
data: Ticket;
fields: [ticketNo, title, refundCents];
filter: refundCents > 0;
on select(row) -> navigate("Queue", {
ticket: row.ticketNo
});
}
}The `Inbox` view: parameters bound to the domain, a `use` of the library’s Inbox module, and a list component whose `select` event navigates to the queue with a row binding.
The whole file is CI-tested: pherolang check examples/ checks every surface in the tree, and the example harness compiles each one on every run. What you see above is the input to the artifact below.
Neighbours
How it relates to the other surfaces
Flows are checked against the rest of the stack: .mox types the data bindings, .actor supplies the capabilities and actors that requires: and roles: resolve against (an empty policy set skips the authorization pass entirely), and .dmn decision services supply data a details component can bind. .deploy binds a frontend component to a flow by path, and the control and route manifest is derived from the checked model.
Commands
How to compile and validate
Three commands, one file. They run from the repository root against the example on this page.
pherolang check examples/support/support.ifml
pherolang ir examples/support/support.ifml -o site/data/artifacts/ifml.json
pherolang artifact check site/data/artifacts/ifml.jsoncheck parses, resolves, validates and type-checks the file and printsOK examples/support/support.ifml. ir writes the artifact and prints nothing on success. artifact check then validates the serialized JSON on its own — no model, no import resolution, no compiler — and prints OK site/data/artifacts/ifml.json.
Directories work too: pherolang check examples/ enters project mode and checks every supported surface under the tree, each file's imports resolving from the snapshot.
Artifact
What it produces
One versioned JSON artifact, emitted by the compiler and consumed by whatever reads this surface.
One IfmlModel: views with their containers, components, events and navigation, plus the declared actions, commands and module imports.
The artifact is site/data/artifacts/ifml.json, and it is committed here exactly as the released pherolang binary emits it. Its top-level shape:
views5 entriesactions6 entriesimports4 entries
Provenance
- formatVersion = 2
- The compatibility gate. A reader accepts this number or refuses the file.
- pheroVersion — not present
- This standalone surface artifact is versioned on its own
formatVersion; only the domain model artifact carries the compiler-version stamp. - 11,255 bytes
- 487 lines, two-space indented, in the file's own key order.
The compiled artifact
The first 30 of 487 lines, verbatim — the exact bytes pherolang ir writes, not a hand-written sample. The slice stops at a JSON boundary; the ellipsis marker is outside the JSON, and the full file is site/data/artifacts/ifml.json.
artifacts/ifml.json · lines 1–30
{
"formatVersion": 2,
"views": [
{
"name": "Inbox",
"label": "Support Inbox",
"isLandmark": true,
"isXor": false,
"isModal": false,
"params": [
{
"name": "tickets",
"typeRef": "Ticket",
"default": null
},
{
"name": "folders",
"typeRef": "Ticket",
"default": null
}
],
"properties": [
{
"key": "landmark",
"value": {
"type": "bool",
"value": true
}
}
],… 457 more lines in site/data/artifacts/ifml.json
Regenerate it from the repository root — the second command validates the serialized bytes with no compiler in the loop:
pherolang ir examples/support/support.ifml -o site/data/artifacts/ifml.json
pherolang artifact check site/data/artifacts/ifml.jsonThe whole data directory is regenerated by node scripts/sync-model.mjs (run from site/) with the released binary; CI fails on a one-byte difference.
Reference
Documentation
The normative reference for this surface, rendered from the repository's own documentation.
docs.pherolang.com
Interaction flow reference
Generated from docs/IFML.md in the repository. The page above summarises it; the reference is normative.