Widget, Element, RenderObject
Three trees, three jobs
Most UI frameworks have one tree of long-lived, mutable control objects. Flutter — and therefore Plumix — splits that responsibility three ways, which is what makes rebuilding the entire UI on every state change affordable.
Widget
Immutable configurationA plain, throwaway description of what the UI should look like. Rebuilt constantly; never holds mutable state.
Element
Mutable instance, owns lifecycleLong-lived. Holds the position in the tree, the BuildContext, and any State. Decides whether an incoming widget updates it in place or replaces it.
RenderObject
Layout, paint, hit-testDoes the actual geometric work. Receives constraints, reports a size, paints into the layer tree, and answers hit-tests.
Widgets are cheap descriptions
Because a widget is immutable and holds no lifecycle, constructing one costs almost nothing. You are allowed to rebuild large subtrees on every frame; the framework diffs the result against the element tree and only touches what actually changed.
// A widget is a description, not an instance. Creating one is cheap —
// the framework decides whether it needs a new element behind it.
public sealed class Badge : StatelessWidget
{
public Badge(string label) => Label = label;
public string Label { get; }
public override Widget Build(BuildContext context) =>
new Container(
padding: new Thickness(8, 4),
child: new Text(Label)
);
}Update or recreate
Each widget produces an element via CreateElement(). When a parent rebuilds, the existing element compares the new widget against the old one and takes one of two paths:
- Update in place — the runtime type and
Keymatch. The element keeps its identity, itsStateand its render object, and only the changed properties propagate downward. - Recreate — the type or key differs. The old element is unmounted, its state disposed, and a fresh subtree is built.
This is why keys matter when reordering a list: without them, position alone decides matching, and state follows the slot rather than the item.
Where Avalonia fits
Avalonia is used as infrastructure, not as a UI layer. It supplies the window, the platform lifecycle, raw input events and a GPU-backed drawing surface. Once a frame begins, the measure, arrange and paint decisions are made entirely by Plumix render objects — so a control ported from Flutter lays out the way its Flutter original does, not the way an equivalent Avalonia control would.
Continue with the layout protocol to see how constraints and sizes flow through that render tree, or stateful widgets for where mutable data lives.
