Deterministic rendering

Slap yourself if

You assume the same inputs will always produce the same UI without enforcing it.

Why this exists

Deterministic rendering exists because modern UIs are full of hidden sources of nondeterminism: async timing, concurrent updates, environment-dependent APIs, and side effects during render. Without constraints, identical user actions can produce different screens.

Mental model

Rendering is a pure function only if you make it one. Deterministic rendering means the UI output is fully determined by explicit inputs at a specific logical time — not by when promises resolve or which task ran first.

  • State updates arrive from multiple async sources.
  • Rendering may be interrupted, replayed, or reordered.
  • Side effects or time-based reads leak into render.
  • The final UI depends on scheduling, not just data.
  • Reading mutable globals or clocks during render.
  • Triggering side effects while rendering.
  • Assuming render order is stable under concurrency.
  • Letting async results mutate state mid-render.

Deterministic rendering means the UI output is fully determined by explicit state and inputs, producing the same result regardless of scheduling, timing, or render retries.

  • Render logic depending on Date.now or Math.random
  • Effects that change state during render
  • UI flicker that disappears under logging
  • Bugs that can’t be reproduced reliably

Deep dive

Requires Pro

Premium deep dives include more internals, more scars.

Why modern renderers break naive determinism

How nondeterminism turns into production bugs

Determinism versus flexibility

Debugging nondeterministic renders

When strict determinism is unnecessary