This guide explains how incrementalRendering works in Tinky and how to pick
the right strategy for your CLI. It focuses on behavior that affects rendering
correctness, output stability, and performance.
Tinky supports three effective modes: disabled, line-diff, and run-diff. You
set the mode with the incrementalRendering option in render.
falseor omitted disables incremental rendering.trueenables run-diff mode.{ strategy: "line" }enables line-diff mode.{ strategy: "run" }enables run-diff mode.{ enabled: false }disables incremental rendering.
Use this example as a starting point:
import { render } from "tinky";
render(<App />, { incrementalRendering: true });
render(<App />, { incrementalRendering: { strategy: "line" } });
render(<App />, { incrementalRendering: { enabled: false } });Both strategies produce the same visual frame, but they write to the terminal differently. The write pattern affects flicker, update bandwidth, and cursor movement volume.
- Line-diff compares output by line and rewrites changed lines.
- Run-diff compares per-cell content and writes only changed runs.
- Run-diff skips terminal writes entirely when the rendered frame is unchanged.
- Run-diff usually writes fewer bytes when each frame changes in small regions.
- Line-diff can be easier to reason about if your app changes full lines often.
Some runtime modes intentionally bypass run-diff, even when you request it. This keeps behavior predictable in environments where cursor-diff rendering is not the best fit.
- In
debugmode, Tinky writes full frames. - In screen-reader mode, Tinky uses the screen-reader output path.
- In CI mode, Tinky avoids cursor-diff updates.
Interactive rendering coexists with Static output and direct stream writes.
You need to know these interactions when you build logging-heavy CLIs.
- New
Staticcontent is appended once, then the interactive frame is redrawn. useStdout().write(...)anduseStderr().write(...)temporarily clear the interactive frame and then restore it.- Transformer-produced trailing spaces are preserved in both line and run modes.
Tinky includes a scenario-based benchmark suite. Run it when you tune rendering settings, layout bounds, or output diff logic.
- Run
bun run benchmarkto execute the scenario suite. - Review the refreshed
docs/benchmark.mdfor output size and render speed. - Check the
speed vs inkglobal metric to ensure diffing overhead stays low.
If output looks stale or overly noisy, narrow the issue by strategy and runtime mode first. Most rendering differences are configuration- or environment-driven.
- Force line mode with
{ strategy: "line" }and compare output behavior. - Disable incremental rendering to confirm whether diffs cause the issue.
- Check whether
debug, screen-reader, or CI mode is active. - Capture
stdoutwrites from hooks to verify frame restoration order.
Use the API docs for RenderOptions for
the complete option contract and defaults.