Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

App Template

Canonical File Layout

my_app/
  my_app.ax       # Single source file

Minimal App Skeleton

// my_app — Boruna Framework App

type State { value: Int }
type Msg { tag: String, payload: Int }
type Effect { kind: String, payload: String, callback_tag: String }
type UpdateResult { state: State, effects: List<Effect> }
type UINode { tag: String, text: String }

fn init() -> State {
    State { value: 0 }
}

fn update(state: State, msg: Msg) -> UpdateResult {
    UpdateResult {
        state: State { value: state.value + msg.payload },
        effects: [],
    }
}

fn view(state: State) -> UINode {
    UINode { tag: "text", text: "value" }
}

fn main() -> Int {
    let s: State = init()
    s.value
}

Required Types

TypeFields
StateYour app state. Must be a record.
Msgtag: String, payload: <T>. Tag dispatches logic.
Effectkind: String, payload: String, callback_tag: String
UpdateResultstate: State, effects: List<Effect>
UINodetag: String + any additional fields

Required Functions

FunctionSignaturePure?
init()() -> StateNo
update()(State, Msg) -> UpdateResultYes
view()(State) -> UINodeYes

Optional Functions

FunctionSignaturePurpose
policies()() -> PolicySetDeclare allowed capabilities
main()() -> IntStandalone test entry point

If you leave out policies(), the runtime uses PolicySet::allow_all(): every built-in effect capability is allowed and there is no per-cycle effect limit.

Create From CLI

boruna framework new my_app
boruna framework validate my_app/my_app.ax
boruna run my_app/my_app.ax

Policy Template

type PolicySet { capabilities: List<String>, max_effects: Int, max_steps: Int }

fn policies() -> PolicySet {
    PolicySet {
        capabilities: ["net.fetch", "time.now"],
        max_effects: 10,
        max_steps: 1000000,
    }
}