Composition Patterns All
A short map of how WildflowerJS apps fit together. Four kinds of composition, each backed by a small set of concrete features. Use this page to pick which feature you want, then click through to its implementation docs for the details.
The Four Kinds
| Kind | Mechanism | Use it for |
|---|---|---|
| Structural | <template> + data-use-template |
Reusing visual fragments across components. A child slots a piece of UI from its parent. |
| Logic | wildflower.component + wildflower.store |
Owning state and behaviour. Components own UI logic; stores own cross-component or cross-page data. |
| Action | data-action delegation |
Connecting parent UI to child methods (or vice versa) without prop drilling. Click handlers find their owner by walking up the DOM. |
| Temporal | SSR hydration + lazy template resolution | Composing the app over time as scripts and templates arrive. New components register; existing ones rescan; nothing pre-loads. |
Structural Composition
A child component asks its parent for a template by name. The parent (or any ancestor) provides the markup; the child instantiates it and binds its own state. The same child renders differently in different parents, with no JavaScript change.
<!-- Parent provides the template -->
<div data-component="dashboard">
<template data-item-template="userCard">
<div class="card">
<h3 data-bind="name"></h3>
<p data-bind="role"></p>
</div>
</template>
<!-- Child consumes it -->
<div data-component="user-list">
<div data-list="users" data-key="id">
<template data-use-template="userCard"></template>
</div>
</div>
</div>
Resolution walks up the DOM tree from the child. The closest ancestor with a matching template wins. To target a specific component instead of "closest," use data-use-template="userCard@dashboard".
When to reach for it: a child component's visual shape depends on context. Same logic, different look in different parents. Read more in Configurable Templates and Advanced Configurable Templates.
What it is not: data-driven variants on a single child instance. For "render a different template based on a state value," see Dynamic Templates (data-template-key).
Logic Composition
Two primitives, picked by lifespan and scope.
Components
A component owns the state and behaviour for a chunk of UI. Lifecycle is tied to its DOM element: created when the element is inserted, destroyed when the element is removed. State on a component is private to that instance.
wildflower.component('counter', {
state: { count: 0 },
increment() { this.state.count++; }
});
Stores
A store owns state that needs to outlive any single component, or be shared across components, or persist across route changes. Stores are global by name and live for the lifetime of the application.
wildflower.store('cart', {
state: { items: [] },
add(product) { this.state.items.push(product); },
computed: {
total() { return this.state.items.reduce((s, i) => s + i.price, 0); }
}
});
wildflower.component('header', {
subscribe: ['cart'],
// this.stores.cart.total reactively updates
});
When to reach for which: default to a component. Reach for a store when two or more components need the same state, or when state must survive a route change. Read more in Basic Stores and Advanced Stores.
Action Composition
An event handler attached with data-action finds its owning component by walking up the DOM. The button doesn't need to know which component it belongs to; the framework figures it out at click time.
<div data-component="todo-list">
<ul data-list="items" data-key="id">
<template>
<li>
<span data-bind="title"></span>
<!-- This button's click bubbles up to todo-list.removeItem -->
<button data-action="removeItem">✕</button>
</li>
</template>
</ul>
</div>
wildflower.component('todo-list', {
state: { items: [{ id: 1, title: 'Write docs' }] },
removeItem(event, element, details) {
// details.index identifies which item the click came from
this.state.items.splice(details.index, 1);
}
});
The same delegation works across nested components: a button inside a child component can target a method on a grandparent if no closer ancestor handles it. This is how parents "skin" children without coupling: the parent provides the template (Structural Composition), and the actions inside that template still resolve to the parent's methods.
When to reach for it: any time a UI fragment needs to invoke logic owned by something further up the tree. Read more in Event Handling.
Temporal Composition
The framework follows the DOM. Components and templates can register at any time; nothing pre-resolves at startup.
Hydration: claim and adopt
Server-rendered HTML carries state inline (input value attributes, bound text nodes, list items already populated). On the client, the framework scans for data-ssr markers, parses state out of the live DOM, attaches reactivity to the existing nodes, and only renders fresh content where SSR didn't reach. No double-render. No flicker. Read more in Server-Side Rendering.
Lazy template resolution
A child component's data-use-template lookup runs at first-render time, not at scan time. As long as the parent's template is in the DOM by the moment the child renders, resolution succeeds. Templates added later can be picked up explicitly via wildflower.rescanItemTemplates(componentId).
Inline fallback content
If a referenced template hasn't loaded yet (or never will), the framework falls back to inline content placed inside the data-use-template element. Soft failure mode for asynchronous code splitting.
<div data-use-template="fancyCard" data-with="item">
<!-- Fallback if fancyCard isn't registered yet -->
<div><span data-bind="item.title"></span></div>
</div>
When to reach for it: mostly automatic. The patterns matter when you ship a multi-file app where templates and components arrive out of order. Read more in Configurable Templates and SSR.
Three Principles That Follow
The four kinds compose into three working principles users tend to hit in practice.
import(). Persistence is opt-in inside store methods. Bundle size scales with what you actually use.
Where to Go Next
- Components for the basics
- Configurable Templates for structural composition in detail
- Dynamic Templates for data-driven variants
- Single-File Components for the standards-only patterns that deliver SFC ergonomics
- Basic Stores for cross-component state
- Server-Side Rendering for hydration internals