Skip to content

Reconciler

wybthon.reconciler

reconciler

Reconciliation engine: mounting, patching, and unmounting VNode trees.

This module is the bridge between the virtual DOM and real DOM. It implements the diffing algorithm that translates VNode trees into attribute writes, child insertions, and node removals.

Mental model:

  • Components run once. A function component is invoked a single time during mount. Its returned VNode tree is mounted directly. Reactive updates flow through reactive holes embedded in that tree, not by re-running the component body.
  • Reactive holes are _dynamic VNodes whose getter is re-evaluated by an effect when its dependencies change. They're created automatically whenever a callable child or callable prop value appears in the tree, and explicitly via dynamic.
  • Components return a VNode (or a value coercible to one). The idiomatic style is to return a static tree and use dynamic for explicit reactive subtrees; a returned zero-arg callable is also accepted and is wrapped in a single reactive hole for convenience (handy when authoring higher-order components).

Public surface:

  • render: top-level entry point.
  • mount: create DOM for a new VNode.
  • unmount: tear down a VNode and its DOM.
  • patch: diff two VNodes and apply DOM changes.

Functions:

Name Description
render

Render a VNode tree into a container element.

mount

Mount a VNode (or string) into container, returning its DOM element.

unmount

Unmount vnode, disposing its effects, ownership scope, and DOM.

patch

Diff old against new and apply minimal DOM changes inside container.

render

render(vnode: VNode, container: Union[Element, str]) -> Element

Render a VNode tree into a container element.

Subsequent calls with the same container patch the existing tree in place; only the differences are applied. Pass None (via the internal API) to unmount.

Parameters:

Name Type Description Default
vnode VNode

The root VNode to render.

required
container Union[Element, str]

An Element wrapper or a CSS selector string identifying an existing DOM node.

required

Returns:

Type Description
Element

The wrapped container Element. Useful for chaining or for

Element

retaining a reference to the mount point.

Example
from wybthon import h, render

render(h("h1", {}, "Hello, world!"), "#app")

mount

mount(vnode: Union[VNode, str], container: Element, anchor: Any = None) -> Element

Mount a VNode (or string) into container, returning its DOM element.

Parameters:

Name Type Description Default
vnode Union[VNode, str]

The VNode to mount. Strings are coerced to text VNodes.

required
container Element

The parent element wrapper.

required
anchor Any

Optional sibling DOM node to insert before. When None, the new element is appended to container.

None

Returns:

Type Description
Element

The mounted Element wrapper.

unmount

unmount(vnode: VNode) -> None

Unmount vnode, disposing its effects, ownership scope, and DOM.

Calls cleanup on the owning component context (if any), removes delegated event handlers, runs on_cleanup callbacks, and detaches the underlying DOM node from its parent.

Parameters:

Name Type Description Default
vnode VNode

The VNode to tear down. Safe to call on already-unmounted nodes (becomes a no-op).

required

patch

patch(old: Optional[VNode], new: VNode, container: Element) -> None

Diff old against new and apply minimal DOM changes inside container.

Same-type VNodes are patched in place (props and children diffed); different types are unmounted and remounted at the same anchor.

Parameters:

Name Type Description Default
old Optional[VNode]

The previously-rendered VNode, or None for the initial mount.

required
new VNode

The new VNode to render.

required
container Element

The parent element wrapper.

required

What's in this module

The reconciler walks a previous and next VDOM tree and applies the minimal set of DOM mutations to bring the page into sync. It handles keyed lists, fragments, components, text nodes, and reactive holes.

Most users never call into this module directly. render mounts a tree and the reconciler kicks in for subsequent updates. Read this page if you're contributing to Wybthon, debugging a diffing bug, or curious how holes plug into the patching loop.

Key responsibilities

Concern How the reconciler handles it
Element diffing Matches by tag. If tags differ, the old subtree unmounts.
Children Keyed lists use a longest-increasing-subsequence move pass; unkeyed children diff by index.
Components A component's body runs once; the reconciler updates props on the existing component instance.
Reactive holes Each hole is an effect; the reconciler patches only the affected node when the signal updates.
Cleanup Unmounting a node disposes the corresponding owner, recursively.

See also