Skip to content

MESH v0.10.0

Choose a tag to compare

@github-actions github-actions released this 10 Oct 04:14
· 72 commits to main since this release
da4d9b9

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) and updateChanges(render, { base, changes }) return the new render and render-patch-v1 patches (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, the mesh-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. compileProgram infers 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 boolean when, and a last default; the first that holds is rendered. The compiler writes it as the mesh-ifs it stands for, so template-v1 and the runtime are unchanged. Provisional, like mesh-if.
  • Errors you can match on. MeshInternalError, MeshVersionError and the new MeshUsageError carry a stable code; runtime diagnostics gain an optional hint. 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-v1 and the manifest format are unchanged, and a program that does not use the new constructs renders exactly as in 0.9. mesh-slot gains an optional name prop; a manifest that declares it without one still works for the default slot.
  • Rust. Tree::root and TreeChild::Node hold an Rc<Node> (code that reads a tree is unchanged by auto-deref; code that builds one, which only a render does, is not). update_with takes the snapshot instead of copying it.
  • Messages. assembly-composite-children now 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-compiler or @valancex/mesh-runtime ^0.9.0 does not receive 0.10.
  • WebAssembly. The modules' exports are internal and changed (mesh_update, mesh_update_changes, mesh_release, mesh_infer and 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.