Repository navigation
MESH v0.10.0
MESH v0.10.0 release notes
Prepared 2026-10-10 (not yet released: v0.9.0 is the latest release).
v0.10 makes an application cheap to update and cheap to compose. The runtime turns a new snapshot, or just the edits to the last one, into patches that touch only what changed; composites take children, named slots and events; and a program's composites no longer need a hand-written contract. The public APIs were reviewed against the API design principles before this release; the review record is docs/superpowers/specs/2026-10-09-api-design-review.md.
Highlights
- Updates.
update(render, snapshot)andupdateChanges(render, { base, changes })return the new render andrender-patch-v1patches (setProp,removeProp,setText,insert,remove,move,replace). A node whose inputs are unchanged is the same node, and the work is proportional to the change: on a keyed list of 10,000 items with one changed, about 22 ms from JavaScript through changes, against 460 ms for a full render.diff(previous, next)computes the edits between two snapshots.render.version,render.release()and[Symbol.dispose]manage what the module keeps;render()keeps nothing. - Composition. A composite's template places an occurrence's children with
mesh-slot, and, by name, themesh-fills of an occurrence with<mesh-slot name>. A composite declares events and forwards them by naming one as a handler. Identity extends without changing any existing key. - No contract to write.
compilePrograminfers the manifest entry of every listed component the manifest does not declare: props from the arguments its occurrences pass, events from the handlers it forwards. The reserved tags a program uses are declared for it. A declared entry is used as written. mesh-fragment. Content without a node: a composite, a conditional alternative, a switch case or a repeat item can be text or several nodes by writing a fragment, and MESH wraps nothing on the author's behalf. Provisional. A fragment cannot start the program's root (assembly-root-fragment).- Maximal text runs. Text on either side of a conditional or a repeat that chose nothing is now one run, as a render tree's runs are meant to be, so a server's single text node can be matched by the client.
mesh-switch. Cases with a booleanwhen, and a last default; the first that holds is rendered. The compiler writes it as themesh-ifs it stands for, sotemplate-v1and the runtime are unchanged. Provisional, likemesh-if.- Errors you can match on.
MeshInternalError,MeshVersionErrorand the newMeshUsageErrorcarry a stablecode; runtime diagnostics gain an optionalhint. New diagnostic codes:invalid-switch,runtime-changes-base-mismatch,runtime-invalid-change,runtime-changes-disagree. - Stability tiers. API stability says what each surface promises: Stable, Provisional (
mesh-if,mesh-each,mesh-switch) and Internal.
Compatibility
- Additive for hosts.
render,dispatch,declaredEvents,compile,check,checkProgram,template-v1,render-v1and the manifest format are unchanged, and a program that does not use the new constructs renders exactly as in 0.9.mesh-slotgains an optionalnameprop; a manifest that declares it without one still works for the default slot. - Rust.
Tree::rootandTreeChild::Nodehold anRc<Node>(code that reads a tree is unchanged by auto-deref; code that builds one, which only a render does, is not).update_withtakes the snapshot instead of copying it. - Messages.
assembly-composite-childrennow covers fills as well as children, and its message changed; match on the code. - npm. All packages move to 0.10.0 together. Before 1.0 a minor is a new range: a package that depends on
@valancex/mesh-compileror@valancex/mesh-runtime^0.9.0does not receive 0.10. - WebAssembly. The modules' exports are internal and changed (
mesh_update,mesh_update_changes,mesh_release,mesh_inferand others); a package checks for the exports it needs, so a package is always built with its own module.
Not decided
Recursion in composites, and whether mesh-switch's lowering should become a runtime construct.