# InkRendererBackend

Source: /tuil/docs/reference/packages/ink/api/ink-renderer-backend
Locale: en

class exported by @mwillbanks/tuil-ink.



{/* Generated by tooling/docs/generate-reference.ts. */}

## class [#class]

Public class exported by `@mwillbanks/tuil-ink`.

```ts
export class InkRendererBackend implements RendererBackend<InkRendererTree> {
  readonly id = "ink";
  readonly capabilities = new Set([
    "ink",
    "renderer-application",
    "react-ink-components",
    "pointer",
    "scroll",
    "clipboard",
    "alternate-screen",
    "inline",
    "static",
    "json",
    "silent",
    "embedded",
  ] as const);
  #sequence: number;

  constructor() {
    this.#sequence = 0;
  }

  render(tree: InkRendererTree, context: RendererContext): RendererFrame {
    if (context.signal.aborted) throw context.signal.reason;
    const scene = normalizeRendererScene(
      tree,
      context.capabilities.width,
      context.capabilities.height,
      context.capabilities.hyperlinks,
    );
    const frame = frameText(scene);
    return Object.freeze({
      width: context.capabilities.width,
      height: context.capabilities.height,
      sequence: ++this.#sequence,
      timestamp: performance.now(),
      mode: context.mode,
      payload: Object.freeze({
        frame,
        rendered:
          context.mode === "interactive"
            ? `${styledFrameText(scene)}\u001b[0m${cursorOutput(scene.cursor)}`
            : frame,
        semantics: scene.semantics,
      }),
      cursor: scene.cursor,
    });
  }

  diff(
    previous: RendererFrame | undefined,
    current: RendererFrame,
  ): RendererOutput {
    const before = previous?.payload as InkFramePayload | undefined;
    const after = current.payload as InkFramePayload & {
      readonly rendered: string;
    };
    const mode = current.mode ?? "interactive";
    const unchanged =
      mode === "json"
        ? JSON.stringify(before) === JSON.stringify(after)
        : before?.rendered === after.rendered;
    const rows = rendererChangeRows(before, after, unchanged);
    const changed = unchanged ? 0 : changedCellCount(before, after, rows, mode);
    const dirty = dirtyOutput(before?.frame, current, after.frame, rows);
    return Object.freeze({
      bytes: outputBytes(mode, current.payload, after.rendered, changed),
      fullFrame: mode !== "silent",
      changedCells: mode === "silent" ? 0 : changed,
      ...dirty,
    });
  }
}
```

## Members [#members]

| Member          | Type                                                                                                                                                                                       | Required | Description                                                                                                                                                                                                                             | Related types                                                           |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `id`            | `"ink"`                                                                                                                                                                                    | Yes      | The `id` member uses the `"ink"` contract.                                                                                                                                                                                              | —                                                                       |
| `capabilities`  | `Set<"static" \| "ink" \| "renderer-application" \| "react-ink-components" \| "pointer" \| "scroll" \| "clipboard" \| "alternate-screen" \| "inline" \| "json" \| "silent" \| "embedded">` | Yes      | The `capabilities` member uses the `Set<"static" \| "ink" \| "renderer-application" \| "react-ink-components" \| "pointer" \| "scroll" \| "clipboard" \| "alternate-screen" \| "inline" \| "json" \| "silent" \| "embedded">` contract. | —                                                                       |
| `#sequence`     | `number`                                                                                                                                                                                   | Yes      | The `#sequence` member uses the `number` contract.                                                                                                                                                                                      | —                                                                       |
| `__constructor` | `any`                                                                                                                                                                                      | Yes      | The `__constructor` member uses the `any` contract.                                                                                                                                                                                     | —                                                                       |
| `render`        | `(tree: InkRendererTree, context: RendererContext) => RendererFrame`                                                                                                                       | Yes      | The `render` member uses the `(tree: InkRendererTree, context: RendererContext) => RendererFrame` contract.                                                                                                                             | [`InkRendererTree`](/tuil/docs/reference/packages/ink/api/ink-renderer-tree) |
| `diff`          | `(previous: RendererFrame \| undefined, current: RendererFrame) => RendererOutput`                                                                                                         | Yes      | The `diff` member uses the `(previous: RendererFrame \| undefined, current: RendererFrame) => RendererOutput` contract.                                                                                                                 | —                                                                       |

## Parameters [#parameters]

This declaration has no public members.

## Returns [#returns]

This declaration does not return a value.

## Throws [#throws]

No thrown errors are documented for this declaration.

## Related types [#related-types]

* [`InkRendererTree`](/tuil/docs/reference/packages/ink/api/ink-renderer-tree)

## Source [#source]

[View the secondary source reference](https://github.com/mwillbanks/tuil/blob/main/packages/ink/src/renderer-backend.ts)

## Package [#package]

[@mwillbanks/tuil-ink](/tuil/docs/reference/packages/ink)
