[ AxiomCore · Documentation ]
Acore UI
Reference for the Acore UI profile, covering pages, state, actions, components, contract operations, routes, forms, styles and target capabilities.
Acore UI is the UI profile of the Acore language. You write pages,
components and styles in .acore, and a UI host renders them on web,
Android Emulator or iOS Simulator. Acore stays the editable source: the
compiler keeps generated output in memory, and application source has no
JavaScript escape hatch.
This page describes the profile compiled by Axiom CLI 0.149.1 (acore-ui/v6).
The examples were checked with axiom ui check from that release inside a
complete module. The logical-submission excerpt also needs a contract with a
durable submission mapping. Commands, hosts and packaging are in
App lifecycle and targets.
Project files
| File | Purpose |
|---|---|
*.acore | Authored UI source. The entry module declares app and its pages. |
AxiomDeps.toml | Frontend manifest with type = "frontend". Declares backend contract imports under [contracts.<alias>]. |
.axiom/axiom.ui.lock.json | Contract lock: alias, audience, operations and artifact digest. axiom run prepares it during development; axiom contract resolve writes it explicitly. Commit it. |
axiom.app.toml | Manifest written by axiom ui init for a starter without contract imports: app id, target and source entry. |
AcoreUI.json | Optional editor settings: profile, entry and targets. Editors can also read initializationOptions.frontend. |
A frontend manifest that imports the backend from the task app:
type = "frontend"
targets = ["web"]
[contracts.tasks]
artifact = "../backend/.axiom/contracts/backend.axiom"
baseUrl = "http://127.0.0.1:8080"
audience = "web"
operations = ["create_task", "delete_task", "list_tasks", "update_task"]Manifest fields and lock commands are described in
Imports, amends and variants. The
browser playground shows the same manifest in its AxiomDeps.toml tab beside
Frontend.acore.
The language server and the CLI use the same project graph and target checks.
Unsaved imported .acore files take part in editor checking. Editors default
to the web target; the CLI uses the target you pass with --target.
Smallest application
module example.app.ui
app Example { route "/" => Home }
page Home {
state message: String = "Hello from Acore"
action reset() {
message = "Hello from Acore"
}
view {
SafeArea {
View {
Text(message)
Button(label: "Reset", on_press: reset)
}
}
}
}appmaps paths to pages.- A
pageowns state, operation bindings, actions and a view tree. SafeAreaapplies the host's platform insets. Use it at the outer edge of a screen that must avoid a status bar or display cutout. On Android it lowers to a container fallback and the compiler reports warningAUI028.
Declarations
| Declaration | Meaning |
|---|---|
module a.b.ui | Module name. Also names the build artifact. |
app Name { route "/" => Page } | Routes. See Routes, stores and sessions for typed routes. |
page Name { ... } | A screen with state, bindings, actions and view. |
component Name(props) { ... } | Reusable UI with its own state, events and slots. |
model, record, enum | Types. They can be module-level or scoped to a page or component. |
pure fn name(...): T = expr | Pure function. Can be scoped to a page or component. |
use model|record|enum|function Name from "./file.acore" | Explicit local import. |
use contract Alias from "alias" audience "web" | Locked backend contract import. |
store name(scope: ...) { ... } | Shared state for app, session, route or component. |
styles { ... } | Typed stylesheet. |
Verified contract projection types use the import namespace, for example
Shop.productShopper. Their private fields stay unavailable. Unknown types,
fields, names and unsupported calls are rejected before any artifact is
produced.
State and pure expressions
model Task { id: Int, title: String }
pure fn normalize(value: String): String = value.trim().lower()
page Counter {
state count: Int = 0
state task: Task = {id: 1, title: normalize(" Hello ")}
action increment() { count = count + 1 }
view {
Text(task.title)
Text(to_string(count))
Button(label: "Increment", on_press: increment)
}
}- State initializers are deterministic pure expressions that match their declared types.
- Generic Acore
Intis 64-bit. The portable UI profile rejects values outside -9,007,199,254,740,991 to 9,007,199,254,740,991, the exact JavaScript integer range. Integer arithmetic uses exact intermediates and checks overflow before a value reaches a host number. A backend 64-bit integer that can exceed this range must use a supported exact wire representation. - Pure expressions support checked arithmetic, comparisons, short-circuit
booleans, conditional expressions,
?.,??, typed records, safe String and list indexing, and.length. A negative or out-of-bounds index returns null. Strings count Unicode scalar values. - Allowed calls:
.trim(), ASCII.lower()and.upper(), substring search,interpolate, explicit numeric conversions, and typed.map(),.filter(),.find()and stable.sort(). - Collection callbacks use inline lambdas, for example
items.map(|item| normalize(item.title)). - Pure functions cannot capture state, recurse, access ambient APIs, or call operations or extensions. They do not acquire provider or extension authority. Evaluation has explicit work and nesting limits.
Derived values
page Search {
state draft: String = ""
derived normalized = draft.trim().lower()
derived caption = normalized + "!"
action changed(value: String) { let snapshot = value.trim(); draft = snapshot }
view {
Input(value: draft, on_input: changed, accessibility_label: "Search")
Text(caption)
}
}A derived value is a typed, memoized pure value. Dependencies are ordered and
cycles are diagnosed. You can render a derived value and use it in actions or
operation arguments, but you cannot assign to it. Memoization keeps one
immutable input and result pair per declaration for its owner. It grants no
resource, clock, random or mutable-state capture.
Actions
Actions support typed parameters, immutable let values, if/else,
guard, exact state assignments, operation .run() and .cancel(), awaited
typed results with a terminal on_error handler, static navigation, and
supported element or verified extension calls. Loops, exceptions, unknown calls
and unconsumed syntax are rejected before lowering. An action branch never
becomes an unconditional write.
mutation deletion = Tasks.delete_task(apiKey: apiKey, id: selectedId)
action remove(payload: Selector) {
selectedId = payload.id
await deletion.run() on_error problem { message = problem.message }
}Execution rules:
- Within a synchronous segment, reads see earlier writes. The segment commits atomically before an operation, an element or extension call, or navigation.
- Payloads and locals keep their values across an
await. State reads after resuming use the current live owner. - A failed remote call stops the action or runs its failure handler. It does not undo segments that already committed.
- Queries cancel superseded requests. Actions and mutation bindings ignore a duplicate invocation while one is pending.
action_status.<name>.pendingexposes whether a named action is running.
Event handler signatures:
| Element | Event | Payload |
|---|---|---|
Input, TextArea, InputField | on_input | String |
Checkbox, Switch | on_change | Bool |
RadioGroup | on_change | String |
ViewPager | on_change | Int |
| Other elements | any | none (parameterless action) |
A wrong event signature reports AUI424.
Lifecycle and effects
page Home {
state count: Int = 0
state log: String = ""
action bump() { count = count + 1 }
lifecycle started {
log = "mounted"
cleanup { }
}
effect watch when [count] initial false {
log = to_string(count)
}
view {
Text(log)
Text(to_string(action_status.bump.pending))
Button(label: "Bump", on_press: bump)
}
}lifecycle name { ... cleanup { ... } }starts owned work once on mount. A declared stream can callupdates.run()andupdates.cancel()there.effect name when [dependencies] initial false { ... }runs after commits.initialdefaults totrue. Effects coalesce changes and wait for the previous cleanup.- Cleanup may release declared operations, extensions and elements. It cannot publish state, start operations or navigate.
- Writing to an effect's own direct or transitive dependency is diagnosed. Cross-effect cycles at runtime stop after 32 flushes.
- Navigation resets page state when you re-enter the page. Page state and store-backed preferences have separate lifecycles.
Components
model Task { id: Int; title: String }
component EditableRow(task: Task, caption: String = "Save") {
event save(payload: Task)
slot trailing: Text?
state draft: String = task.title
action saveDraft() { emit save({id: task.id, title: draft.trim()}) }
view {
Input(value: draft, accessibility_label: "Task title")
Button(label: caption, on_press: saveDraft)
Slot(name: "trailing")
}
}
page Home {
state task: Task = {id: 1, title: "First task"}
state message: String = ""
action saved(payload: Task) { message = payload.title }
view {
EditableRow(task: task, on_save: saved) {
Slot(name: "trailing") { Text(message) }
}
}
}Props:
- Local and imported components keep resolved prop types, required and nullable inputs, and closed pure defaults. Props are immutable.
- Each invocation owns independent state, derived values, actions, operations and lifecycle cleanup.
- Changing a prop updates reads and query arguments without erasing local drafts. Reset a draft explicitly, or remove and remount the instance.
Actionprops keep parameterless forwarding.
Events and slots:
- A named event passes one checked payload, or null for an empty event declaration, to the parent action. A parameterless handler may discard it.
- The caller resolves expressions and actions inside a supplied named slot.
- Slots declare allowed element types and cardinality:
Text,Text?,List<Element>or[Text,Button][0..2]. - Missing, duplicate or unknown props, events, placements and slots are diagnosed. Conditional or list wrappers inside bounded supplied slots are rejected.
Identity and reload:
- A component accepts a String or portable Int
key. Keyed lists keep the matching instance through a reorder and dispose removed instances. - Nested local element IDs are isolated per instance.
- A compatible reload keeps typed state. Incompatible signatures or state schemas reset explicitly. The renderer keeps input focus and selection when it restores the same instance.
Component libraries:
- Locked
axiom-component-library/v2packages express node property bindings, slot placement, and bounded state, derived, action and lifecycle behavior. They use the same compiler as local components and expose artifact and export provenance. - Libraries stay data-only. They cannot acquire operation, extension or navigation authority; emit a typed event to the consuming app instead.
- Version 1 libraries keep their passive executable subset. Version 2 rejects legacy transition, accessibility and reload metadata, and Color or Dimension refinement descriptors that cannot be represented faithfully. Use explicit node bindings and theme roles.
- Envelope validation is not consumer validation. Run
axiom packages check-sourceagainst your application.
Contract operations
Import a locked contract, then bind its operations as query (reads) or
mutation (writes). This page uses the task app contract.
use contract Tasks from "tasks" audience "web"
page Home {
state apiKey: String = "dev"
state title: String = ""
derived draft = {title: title}
query tasks = Tasks.list_tasks(apiKey: apiKey)
mutation create = Tasks.create_task(apiKey: apiKey, task: draft)
action submit() {
create.run()
title = ""
}
view {
View {
Input(value: title, placeholder: "Add a task")
Button(label: "Add", on_press: submit)
if tasks.pending { Text("Loading") }
else if tasks.error { Text("Could not load tasks") }
else {
List(items: tasks.data, key: |task| task.id, list_type: "single", span_count: 1, scroll_orientation: "vertical") {
task => Text(task.title)
}
}
}
}
}Lock checks:
- The alias, audience, operation, kind and artifact digest must match the
committed
axiom.ui.lock.json. - The compiler checks argument names against the operation's request fields and explicit URL path placeholders. Schema-bearing verified locks also check argument types, requiredness, result projections and declared error codes. Older locks without descriptors keep a bounded compatibility path.
- Compilation never discovers a live backend as a fallback.
- An unsigned local artifact is allowed for development and reports warning
AUI059. A production release needs an Axiom Cloud signed contract.
Request payloads follow the verified contract, so frontend code never builds an HTTP body:
- A projected request record keeps its public field envelope on web, iOS and
Android. A projection exposing only
completedsends{"completed": true}. - A single unprojected body parameter sends its value as the whole JSON body.
- Path, query and header parameters stay in their declared locations.
Input(value: ...) must reference declared local String state (AUI255).
Use a derived record or a form_model to build a request record from
inputs.
Query policy
page Home {
state apiKey: String = "dev"
state enabled: Bool = false
query tasks = Tasks.list_tasks(apiKey: apiKey) options(debounce_ms: 100, focus: true, reconnect: true) when enabled
action load() { enabled = true }
action reload() { tasks.refresh() }
view {
Text(tasks.status)
Button(label: "Load", on_press: load)
Button(label: "Reload", on_press: reload)
}
}- Policy clauses go in
options(...)before the finalwhen. - A query runs on mount and again when its canonical typed arguments or its
when Boolenablement change. This example starts with no request. - An explicit reload uses fresh arguments. A matching refresh effect is rejected to prevent a duplicate request.
debounce: 150msandpoll: 30stake durations.debounce_msremains supported; contradictory aliases are rejected. Polling pauses for hidden owners and needs foreground events on native hosts. Actions can also join finite named query groups. See Managed logic and concurrency.- Operation states distinguish disabled, debouncing, loading, success, empty, refresh with retained data, error, cancellation and stream states.
refresh()andretry()request one fresh logical call. The runtime keeps the contract's HTTP retry rules.- A failed refresh keeps the previous data and sets
staleanderror. - Declared mutation cache identities drive invalidation across active owners.
- Cursor pagination (
next()), bounded stream reduction, reconnect and resume, and typed optimistic patches need matching locked request and result fields. Unsupported or ill-typed policies are diagnosed.
Coalescing, sessions and limits
- Identical reads share one request. The coalescing identity includes the locked artifact and audience, endpoint and cache identity, canonical validated arguments, invalidation revision and session generation.
- Cancelling one owner leaves other owners of the same query active.
- The coordinator admits at most 256 query flights and 128 waiters per flight. A cancelled callback keeps its flight capacity until the transport settles.
- Work and late events cannot publish into a completed, disposed or changed-session owner.
- A session change cancels old work and isolates private cache partitions. The
public
sessionvalue holds identity, principal, roles and permissions; credentials stay in the runtime transport. - A private backend
batchPolicydoes not merge frontend HTTP requests. To batch, call an explicitly declared, locked public batch endpoint, which keeps each item's outcome. See Integrations and transports.
Typed failure cases
A selected operation schema at version 2 can carry explicit public failure
cases. The operation's error state exposes optional case payloads through
error.cases; only the selected fields are typed. Decoders check the envelope
and case schema and never guess from message text. Owner disposal and
cancellation still prevent stale completion. See
Managed logic and concurrency for
declaring public failures.
Routes, stores and sessions
model PreferencesV1 { theme: String }
store preferences(scope: "app", persist: "preferences", key: "dashboard", version: 2) {
state theme: String = "system"
state compact: Bool = false
migration 1(old: PreferencesV1) = {theme: old.theme, compact: false}
}
store selection(scope: "session") { state task: Int = 0 }
app Dashboard {
route Home "/" => Home
route Edit "/tasks/:id" => Details {
path id: Int
query tab: String = "edit"
layout Shell
}
route Old "/old" => Home { redirect "/" }
not_found Missing
}
page Shell {
view { Text("Task dashboard") Outlet() }
}
page Home {
action edit() { go Edit(id: 1) }
action theme() { update stores.preferences.theme = "dark" }
view { Text(stores.preferences.theme) Button(label: "Edit task", on_press: edit) Button(label: "Dark", on_press: theme) }
}
page Details {
action goBack() { back() }
view { Text(to_string(route.params.id)) Button(label: "Back", on_press: goBack) }
}
page Missing { view { Text("Page not found") } }| Feature | Syntax |
|---|---|
| Stores | store name(scope: "app" | "session" | "route" | "component") |
| Persisted preferences | persist, key, version and typed pure migration N(old: T) = {...}; reset with store name.reset() |
| Typed routes | route Name "/path/:param" => Page { path p: T query q: T = default } |
| Layouts | layout Shell; the layout renders Outlet() |
| Guards | guard <condition> with denied "/path"; signed_out "/path" on the app |
| Redirects and fallback | { redirect "/" } and not_found Page |
| Navigation | go Route(param: value), back(), read route.params.<name> |
| Store writes | update stores.<store>.<field> = value |
| Sessions | session_actions(discover:, sign_in:, sign_out:), then session sign_in() in an action and session.status in a view |
Guards need their denied destination on its own line. Session discovery and
sign-in operations must return the complete public Session type (AUI450).
Behavior:
- Unknown and malformed URLs have defined results.
- Each navigation entry owns its draft. App preferences survive navigation; session, route and component state clears at its ownership boundary.
- Versioned preferences and drafts hydrate through bounded platform adapters, expose readiness and failure, and support typed pure migrations and explicit reset. Credentials stay at the transport or secure-store boundary.
- On native hosts, mounting an owner publishes the current session snapshot, including discovery updates that completed before the owner subscribed.
- A session change resets mounted route pages and layouts, releases child component owners, and clears the previous principal's drafts before new component owners mount. These rules follow the declared owner kind, not generated route identifiers.
Forms
form_model binds typed structured values to a locked mutation. This excerpt
from the task app validates against the contract and maps a typed server
failure to a field:
model Draft { title: String }
page Home {
state apiKey: String = ""
state draft: Draft = {title: ""}
mutation create = Tasks.create_task(apiKey: apiKey, task: draft)
form_model composer(values: draft, submit: create, validation: FormValidation.contract) {
field title(parse: raw.trim(), timing: "submit", message: "Enter a task title")
server Tasks.Failures.duplicate(field: .title, message: server_error.payload.message)
}
action add() { form composer.submit() }
view {
Input(value: composer.fields.title.raw, placeholder: "What needs doing?", accessibility_label: "Task title")
Button(label: "Add task", disabled: composer.pending, on_press: add)
Text(composer.fields.title.error ?? "")
}
}What a form provides:
- Typed defaults and result,
touched,dirtyandstatus, field errors and summary errors. - Parsing (
parse:) separate from pure field and cross-field validation (validate:andrule), debounced declared async validation (async), stable keyed arrays (array), and typed server-error mapping (server). - Field
timingis"change","blur"or"submit". Form actions:form name.submit(),retry(),reset(), and array edits such asform name.append.tags(item: ...).
Contract validation (validation: FormValidation.contract):
- Inherits the mutation's public structural and pure validation rules. It needs a compatible, checked draft-to-request mapping.
- Field timing and messages control feedback. Local checks can add rules.
- Submission validates the complete request again before transport. A private backend rule is not copied into the form.
- Private payload fields, a wrong contract alias, missing selected validation and unknown form fields are rejected.
Field values and issues:
fields.<name>.rawkeeps an invalid string whilefields.<name>.valuebecomes null. The last parsed draft value stays separate.issuesholds at most 64 entries and 32 KiB. Each entry hasfield,code,messageandorigin(parse,local,contractorserver).issues_truncatedreports when entries were dropped.fields.<name>.error,errorsand legacy server-code mappings remain available.
Submission and controls:
- A pending submission dispatches once. A failure keeps the draft. A stale reply cannot overwrite newer input. Route disposal cancels owned work.
- Controls associate labels and errors, submit on Enter or confirm, focus the first error and announce failures.
- Single-line bound native inputs default to a Done key. Done closes the keyboard after a successful submission; a validation or server error keeps error focus. Outside a form, Done ends editing. Explicit confirm types and multiline inputs keep their declared behavior.
- A mapped server field error survives focus changes and unrelated edits.
Editing the rejected field clears it;
retrystarts fresh validation;resetclears the form metadata.
Generated native adapters are tested separately from physical keyboard and accessibility behavior. Check input, keyboard and accessibility on the mounted target you ship.
Uncertain writes and logical submission
Uncertain writes:
- A transport failure, timeout or cancellation after a mutation was sent
cannot prove the write failed. The mutation exposes
uncertain(for examplecreate.uncertain) and anindeterminatestatus, keeps the optimistic view and requests an authoritative query refresh. - A definite, checked business or validation failure can revert its patch. A newer query revision is preserved.
- If local reconciliation fails after a successful reply, the app requests a read instead of showing a false rollback.
- Query repair alone does not give exactly-once writes. Use receipt-based resolution where the provider contract supplies it.
Logical submission:
mutation save = Workflow.save_draft(draft: draft) options(
idempotency: IdempotencyMode.logicalSubmission
)- Allowed only when the selected signed contract declares an enforced durable
admission ledger and a dedicated transport-header mapping. An
idempotentflag alone does not qualify. Otherwise the check fails withAUI440. - The public mapping uses
axiom-logical-submission/v1inaxiom-ui-operation-schema/v3, signed UI metadata v2 and minimum artifact reader 3. A stale lock, missing mapping or incompatible reader fails during checking. The mapping does not remove a required body argument. - The backend may capture the key as exactly one required
Stringheader with no default and pass it to a receipt-backed managed transaction. That capture is removed from the frontend's request arguments; the host supplies the header. Optional, non-string, defaulted or duplicate (case-insensitive) captures are rejected. The resolution-control header cannot be captured as input. - The web or native host creates a secure random key. Do not put it in draft state or persisted preferences. A pending duplicate submit dispatches once.
- An uncertain submission keeps its key and normalized input. Submitting it
again sends the same key with
x-axiom-submission-resolution: only. The server re-authenticates and checks the guard, authority partition and input fingerprint before replaying a completed response. - Resolution never starts a new invocation, even after the ledger's retention expires. A missing, running or indeterminate receipt stays unresolved. After a confirmed terminal result, a new explicit submission gets a new key; changed input is a distinct submission.
- If CORS is enabled, its policy must allow the declared key header and
x-axiom-submission-resolution. The compiler rejects a mapping whose CORS policy omits either. A durable provider must pass its persistence and readiness checks; memory coordination cannot qualify. - A compatible native development reload transfers unresolved keys only in an
in-memory
acore-native-reload/v2snapshot with the same settled session, operation, contract, schema and transport mapping. Changed authority or a changed artifact requires replacement. Records are bounded to 256 and 1 MiB of canonical input identity, with 64 KiB per submission. Default observations omit keys and inputs. This is not a persisted draft or a crash recovery mechanism.
Owners and stale work
App, session, route and component owners fence asynchronous results by generation and revision.
- Navigation, owner removal, session replacement and hot reload retire old work and run permitted cleanup.
- Cleanup can cancel owned work and release element or extension resources. A disposed owner cannot mutate stores, navigate, submit operations or emit business events.
- Owner disposal fences late responses; state segments that already committed keep their meaning.
- A rejected guest revision proposal reports a typed conflict. The host validates all authorized patches against a private candidate before committing, so one invalid patch never publishes a partial update.
- Frontend stores are local scoped state unless a separately qualified durable
adapter is selected. A UI commit before an
awaitand a backend transaction are different boundaries.
Elements and capabilities
Portable primitives include:
| Family | Elements |
|---|---|
| Layout and content | View, Text, Image, Svg, SafeArea |
| Scrolling and collections | ScrollView, List, ViewPager, refresh and scroll-coordinator elements |
| Text entry | Input, TextArea |
| Media and surfaces | Video, WebView, Overlay, BlurView |
| Interaction | Button, Pressable |
| Components | dialogs, forms, popovers, sheets, selection, swipe actions, sorting, switches |
This list is not a target guarantee. In the 0.149.1 registry, Video,
WebView and BlurView are unsupported on web and conditional on Android and
iOS. A List inside another scrolling container must set
enable_nested_scroll: true (AUI247). Query the versioned registry that
ships with your CLI:
axiom ui capabilities --target web
axiom ui capabilities --target android --kind element
axiom ui capabilities --target ios --query button --jsonAcore frontend registry ... · 243 entries · sha256:65b14a79af78
...
web: 212 conditional · 31 unsupported--kind accepts element, component, property, at-rule, datatype and
selector. --query matches a capability ID, renderer name or Acore name. The
compiler rejects an unsupported capability instead of silently changing the
view.
Assets, themes and styles
- Local assets use safe paths relative to the source package, for example
images/mark.svg. Absolute paths and traversal are rejected. The compiler records each asset digest, and the CLI verifies it before copying the asset into an opaque cache. - Theme tokens and stylesheets are parsed into typed UI records. Supported
properties, selectors, at-rules and datatypes are listed by
axiom ui capabilities. Do not assume browser CSS is portable.
Responsive layouts
To give a scrollable body the space left below a heading, use a column with an explicit screen height. A fixed body height can extend past the visible screen and clip its last controls on small devices.
styles {
.screen {height: 100vh; display: flex; flex-direction: column}
.body {height: 0px; flex-grow: 1; flex-shrink: 1; min-height: 0px; width: 100%}
}Apply .screen to the outer container and .body to its ScrollView child.
Acore uses three viewport classes measured in logical pixels:
| Class | Logical viewport width |
|---|---|
compact | Below 600 |
regular | 600 through 1023 |
wide | 1024 and above |
styles {
.catalog { gap: 12px }
viewport compact {
.catalog { gap: 8px }
.actions { flex-direction: column }
.primary, .secondary { width: 100% }
}
viewport regular {
.actions { flex-direction: row }
}
viewport wide {
.catalog { gap: 16px }
}
}viewport blocks are not CSS media queries. The compiler keeps the class in the
UI IR, and each host derives the same class from its logical viewport.
Structural integer properties take a typed responsive(...) value. All three
names are required, and each value is checked against the property's range:
List(
items: products.data,
key: |product| product.id,
list_type: "flow",
span_count: responsive(compact: 1, regular: 2, wide: 3),
scroll_orientation: "vertical"
) { product =>
Text(product.name)
}A viewport change keeps normal page state. Web listens for browser resizes; iOS and Android use logical dimensions from their native hosts. Arbitrary breakpoint expressions and target-specific media-query strings are outside the portable profile.
Diagnostics seen on this page
| Code | Severity | Meaning |
|---|---|---|
AUI010 | error | The committed UI lock cannot be read. |
AUI028 | warning | SafeArea lowers to the Android container fallback. |
AUI059 | warning | The contract is an unsigned local development artifact. |
AUI247 | error | A nested List needs enable_nested_scroll: true. |
AUI255 | error | An input value must reference declared local String state. |
AUI424 | error | An event handler has the wrong signature. |
AUI450 | error | An application-profile rule failed, for example a guard without denied. |
AUI440 | error | logicalSubmission needs a durable transport mapping. |
Related
- App lifecycle and targets: check, run, test, build, package and host compatibility.
- Frontend tests: interaction suites.
- Task app: a complete web application with a SQLite backend.
- Syntax: shared authoring shortcuts such as resolved endpoint types and failure inference (source preview; they need matching compiler, host and editor versions).