Cookbook

Real recipes for the shapes most apps actually need — each built from the plain files you'd write yourself, with no build step and Zoijs's safe-by-default rendering throughout. Every recipe uses only the public API; copy a page, change the endpoints, and you have a working feature.

Recipes#

  • CRUD — list, create, edit, and delete against a REST API, with @zoijs/resource for reads and @zoijs/action for writes.
  • Debounced search — a typeahead that waits for the user to stop typing, cancels stale results, and never races.
  • Infinite scroll — load more as the user reaches the end, with an IntersectionObserver and clean teardown.
  • File upload — a native file input, a real progress bar, and a safe object-URL preview.
  • Data table — a sortable, filterable table over a keyed each, so rows are reused (not rebuilt) as the view changes.
  • Charts (via a plain library) — drop in any vanilla chart library with a ref; no wrapper, no plugin.
  • Animations — enter, toggle, and leave with CSS transitions and the Web Animations API via ref; no motion library.
  • Icons — inline SVG, a <use> sprite, or a tiny icon component; no icon package.

Two more common shapes have their own dedicated pages:

  • Forms & validationForms (@zoijs/forms).
  • AuthenticationAuthentication (a recipe, not a package — by design).

The pattern behind them#

Most of these recipes are the same three moves:

  1. Reads are a resourceloading() / data() / error() / refresh().
  2. Writes are an actionpending() / error() / run(), then refresh() the read.
  3. The view is a function returning html, where ${() => …} binds the reactive readers to the DOM. One value changes, one node updates — no re-render.

Because rendering is fine-grained and text is inert by default, these stay fast and safe without extra ceremony. Where a recipe touches a sink that can be unsafe (an object URL, a third-party library's DOM), the page calls it out and shows the safe form.


Next: CRUD.