Why LemonadeJS v6 Exists

LemonadeJS v6 is built around a single goal: the shortest reliable path from an intent to a working, verifiable component, whether the author is a person or an AI agent.

Two trends shape the design. Components are increasingly drafted by AI agents, and they are increasingly expected to run anywhere: in plain HTML, inside a React application, or as a standard web component. v6 is small, explicit, and verifiable, so that both authors and their tools can move quickly and trust the result.

Design principles

Setup runs once; bindings are precise. A component’s function runs a single time. From then on, fine-grained bindings update only the parts of the DOM that depend on a value that changed. There is no re-render cycle to reason about and no dependency arrays to maintain, which removes a common source of stale values.

State is mutable by design. Assign to a property to notify observers, or mutate a structure in place and call touch() when finished. Large datasets are edited directly: the datagrid block updates 5,000 of 100,000 rows and re-renders its visible window in roughly 4 ms, measured in Chrome.

Every component declares a contract. component(name, contract, fn) defines props, types, defaults, events, and API in one place. From that single definition the engine derives runtime prop coercion, a generated .d.ts, a machine-readable contract.json, and a standard custom element, so a tool can read a component’s interface in a single request rather than inferring it from source.

Conformance is verifiable. verify(Component) exercises the contract, every prop and every deployment path, and fails on any engine warning. “Does this component conform?” has a definite, mechanical answer.

Diagnostics are explicit. Each engine warning carries a stable code (for example, LJS-203: update loop detected), and explain('LJS-203') prints a full diagnosis in development builds.

Runs where you need it

A v6 component is portable. adaptReact() turns any contract component into a first-class React component (tested against React 18 in StrictMode), and createWebComponent() exposes it as a custom element everywhere else. The engine is 9.3 KB gzipped with zero dependencies: contracts, two-way binding, keyed lists, resource(), web components, and error containment included.

Measured, not asserted

The Studio catalog is built and continuously verified through the same loop v6 optimizes:

  • 43 blocks, 1,049 behavior tests, every block passing verify()
  • 62 real-Chrome geometry probes (popup anchoring, drag commits, virtualization windows)
  • 100,000 modal create/destroy cycles leave zero detached DOM nodes, confirmed with heap snapshots (see Destroy)

Continue with State for the mutability model, computed() for derived values, Contracts for publishing, and Destroy.