---
title: renderFrame
description: Render a workflow tree to a GraphSnapshot without executing.
---

Use `renderFrame` to preview the task graph (for CI validation, graph-inspection UIs, or dry-run checks) without executing or persisting anything. `runId` and `iteration` are arbitrary strings used only for snapshot identity.

```ts
import { renderFrame } from "smithers-orchestrator";
import { SmithersCtx } from "@smithers-orchestrator/driver";
import { Effect } from "effect";

const ctx = new SmithersCtx({ runId: "preview", iteration: 0, input: { task: "preview" }, outputs: {} });
const snap = await Effect.runPromise(renderFrame(workflow, ctx));

snap.frameNo;       // 0
snap.tasks;         // TaskDescriptor[]
snap.xml;           // XmlNode | null (see Types)
```

`TaskDescriptor` and `GraphSnapshot` are defined in [Types](/reference/types). Same shape the runtime extracts on every render frame; `renderFrame` doesn't execute or persist.

`outputs` lets you simulate completed upstream tasks:

```ts
const ctx = new SmithersCtx({
  runId: "sim", iteration: 0, input: { x: 1 },
  outputs: {
    analyze: [{ runId: "sim", nodeId: "analyze", iteration: 0, summary: "..." }],
  },
});
const snap = await Effect.runPromise(renderFrame(workflow, ctx));
```

CLI equivalent:

```bash
bunx smithers-orchestrator graph workflow.tsx --input '{"task":"preview"}'
```
