Documentation

Composition

Import a behavior, bind it to your data and change what the call site may change. The state machine stays the behavior's.

Most of an Orb program is composed, not written. A behavior from the standard library (or your own blocks) is imported with uses, then referenced one trait at a time or as a whole orbital. You bind it to your entity and set its knobs; its states and transitions stay exactly as the behavior defines them.

Referencing a trait

lolo
1uses Browse from "std/behaviors/std-browse" 2 3trait BookShelf = Browse.traits.BrowseItemBrowse -> Book { 4 config { 5 browseLook: feed 6 fields: [{ name: "name", label: "Title", variant: h4 }] 7 } 8}

Alias.traits.Name -> Entity takes the trait and rebinds it to your entity. The body may only touch the call-site surface:

OverrideEffect
config { key: value }Set knobs the trait declares
events { OLD: NEW }Rename event keys everywhere in the machine
fields { old: new }Rename the entity fields the trait reads and writes
listens { … }Replace the trait's listens entirely
emitsScope internalKeep every emit inside the orbital

There is no way to add a state, remove a transition or change a transition's effects at a call site. To react differently, add a sibling trait that listens to the behavior's events. That rule is what makes a composed program as checkable as a hand-written one.

Here two standard behaviors are bound to a local Book entity, with no state machine written by hand:

State machine

LibraryPage

on LibraryView · states: 1 · transitions: 0
idle

BookShelf

on Book · states: 3 · transitions: 9
emitsBrowseItemLoadedemitsBrowseItemLoadFailedemitsVIEWemitsEDITemitsDELETE
BrowseItemLoaded
BrowseItemLoadFailed
REFETCH_QUERY
REFETCH_FILTER
REFETCH_PAGE
VIEW
CLOSE
BrowseItemLoaded
BrowseItemLoadFailed
loading
browsing
error

BookFacts

on LibraryView · states: 1 · transitions: 0
idle

MasterListView

on Book · states: 1 · transitions: 1
listensBrowseItemLoadedemitsREORDERemitsVIEWemitsSWIPE_LEFTemitsSWIPE_RIGHTemitsLONG_PRESSemitsLOAD_MOREemitsVIEWemitsDataListLoaded
DataListLoaded
idle
Running live

The shelf at a glance

3

books

1

on loan

Structure and Interpretation

On the shelf

Abelson and Sussman

Communicating Sequential Processes

On loan

Hoare

The Art of Computer Programming

On the shelf

Knuth

The program above as state machines, one per trait: each box is a state, each arrow an event that moves it, and the icons on an arrow are the effects that event runs. A ◇ on an arrow is a guard; hover it to read the check. How to read AVL

std-orb-docex-library.lolololo
1app std-orb-docex-library "1.0.0" 2"std-orb-docex-library — composition: two standard behaviors bound to a local entity and configured at the call site, with no state machine written by hand." 3orbital LibraryOrbital { 4 uses Browse from "std/behaviors/std-browse" 5 uses StatBand from "std/behaviors/std-stat-band" 6 7 entity Book [persistent: docex_books, local] { 8 id : string! 9 name : string! 10 author : string = "" 11 status : "active" | "pending" | "inactive" = active 12 instances [ 13 { id: "B-1", name: "Structure and Interpretation", author: "Abelson and Sussman", status: active }, 14 { id: "B-2", name: "Communicating Sequential Processes", author: "Hoare", status: pending }, 15 { id: "B-3", name: "The Art of Computer Programming", author: "Knuth", status: active } 16 ] 17 } 18 19 entity LibraryView [runtime] { 20 id : string! 21 } 22 23 trait LibraryPage -> LibraryView [interaction, instance] { 24 initial: idle 25 26 state idle { 27 INIT -> idle 28 (render-ui main { type: stack, direction: vertical, gap: lg, children: [@trait.BookFacts, @trait.BookShelf] }) 29 } 30 } 31 32 trait BookShelf = Browse.traits.BrowseItemBrowse -> Book { 33 config { 34 browseLook: feed 35 bodySearch: false 36 fields: [{ name: "name", label: "Title", variant: h4 }, { name: "author", label: "Author", variant: caption }, { name: "status", label: "Status", variant: badge, labels: { active: "On the shelf", pending: "On loan", inactive: "Lost" } }] 37 } 38 } 39 40 trait BookFacts = StatBand.traits.StatBandRender -> LibraryView { 41 config { 42 heading: "The shelf at a glance" 43 items: [{ value: "3", label: "books" }, { value: "1", label: "on loan" }] 44 } 45 } 46 47 page "/library" -> LibraryPage 48}

Importing a whole orbital

lolo
1uses Board from "std/behaviors/std-board" 2 3orbital Hiring = Board.orbitals.BoardOrbital { 4 entity Candidate 5 fields { title: name } 6 extend { referredBy : string = "" } 7 pages { "/board": "/hiring" } 8}

An orbital reference brings the entity, every trait and every page. Its body can rebind the entity, rename fields, add new fields with extend, remap routes, trim traits with omit or only, and set the orbital's declared knobs with config. Imported names are prefixed with your orbital's name, so two imports of the same behavior never collide.

Config at three levels

Knobs live on a trait (trait.config), on an orbital (the knobs it publishes across its traits) and on the app. A trait publishes an orbital or app knob to itself by defaulting its own knob to @config.<knob>, and resolution walks from the call site to the orbital to the app. A declared knob no trait forwards is an error, and so is overriding a knob that was never declared.

Loading behaviors lazily

lolo
1uses lazy Guide from "./guide" 2 3orbital GuideIntro = Guide.orbitals.GuidePage { 4 pages { "/guide": "/guide/intro" } 5}

A uses lazy behavior is compiled to its own file and loaded only when one of its pages opens, so a large site does not ship every section up front. A lazy alias can only be used as a whole orbital with pages. These documentation pages are lazy behaviors.

Orb

The language where the rule is the program.

© 2026 Almadar. Ljubljana, Slovenia.