Browse documentation

BEYOND QUICK START

Render client-only markup

Describe the view as a Typed template, then choose the DOM renderer at the edge.

This smaller version of the Quick Start counter explains how a template reaches the DOM. Start with a fixed zero. In src/main.ts, html describes the view:

// This view has no local setup, so html is enough.
const Counter = html`<main>
  <h1>Counter</h1>
  <output>0</output>
</main>`;

This view needs no state or component generator. To display it, render into document.body and supply the DOM renderer:

await render(Counter, document.body).pipe(
  Fx.drainLayer,
  Layer.provide(DomRenderTemplate),
  Layer.launch,
  Effect.runPromise,
);

Fx.drainLayer runs the render stream for the lifetime of the layer. Layer.launch keeps it running; Effect.runPromise starts it from JavaScript. Keep this launch at the application entrypoint.

Replace src/main.ts with the complete file below. Open Vite’s local URL: you should see Counter and 0, with no buttons yet.

Complete file

src/main.ts
import { Fx } from "@typed/fx";
import { DomRenderTemplate, html, render } from "@typed/template";
import { Effect, Layer } from "effect";

// This view has no local setup, so html is enough.
const Counter = html`<main>
  <h1>Counter</h1>
  <output>0</output>
</main>`;

await render(Counter, document.body).pipe(
  Fx.drainLayer,
  Layer.provide(DomRenderTemplate),
  Layer.launch,
  Effect.runPromise,
);

The Quick Start counter adds state to this render pipeline. See mounting DOM output for host ownership and teardown.