yaml

$npx mdskill add vercel-labs/json-render/yaml

YAML wire format for `@json-render/core`. Progressive rendering and surgical edits via streaming YAML.

SKILL.md

.github/skills/yamlView on GitHub ↗
---
name: yaml
description: YAML wire format for json-render with streaming parser, prompt generation, and AI SDK transform. Use when working with @json-render/yaml, YAML-based spec streaming, yaml-spec/yaml-edit fences, or YAML prompt generation.
---

# @json-render/yaml

YAML wire format for `@json-render/core`. Progressive rendering and surgical edits via streaming YAML.

## Key Concepts

- **YAML wire format**: Alternative to JSONL that uses code fences (`yaml-spec`, `yaml-edit`, `yaml-patch`, `diff`)
- **Streaming parser**: Incrementally parses YAML, emits JSON Patch operations via diffing
- **Edit modes**: Patch (RFC 6902), merge (RFC 7396), and unified diff
- **AI SDK transform**: `TransformStream` that converts YAML fences into json-render patches

## Generating YAML Prompts

```typescript
import { yamlPrompt } from "@json-render/yaml";
import { catalog } from "./catalog";

// Standalone mode (LLM outputs only YAML)
const systemPrompt = yamlPrompt(catalog, {
  mode: "standalone",
  editModes: ["merge"],
  customRules: ["Always use dark theme"],
});

// Inline mode (LLM responds conversationally, wraps YAML in fences)
const chatPrompt = yamlPrompt(catalog, { mode: "inline" });
```

Options:

- `system` (string) — Custom system message intro
- `mode` ("standalone" | "inline") — Output mode, default "standalone"
- `customRules` (string[]) — Additional rules appended to prompt
- `editModes` (EditMode[]) — Edit modes to document, default ["merge"]

## AI SDK Transform

Use `pipeYamlRender` as a drop-in replacement for `pipeJsonRender`:

```typescript
import { pipeYamlRender } from "@json-render/yaml";
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";

const stream = createUIMessageStream({
  execute: async ({ writer }) => {
    writer.merge(pipeYamlRender(result.toUIMessageStream()));
  },
});
return createUIMessageStreamResponse({ stream });
```

For multi-turn edits, pass the previous spec:

```typescript
pipeYamlRender(result.toUIMessageStream(), {
  previousSpec: currentSpec,
});
```

The transform recognizes four fence types:

- `yaml-spec` — Full spec, parsed progressively line-by-line
- `yaml-edit` — Partial YAML deep-merged with current spec (RFC 7396)
- `yaml-patch` — RFC 6902 JSON Patch lines; applied to the working spec, so later `yaml-edit` fences see them
- `diff` — Unified diff applied to serialized spec

## Streaming Parser (Low-Level)

```typescript
import { createYamlStreamCompiler } from "@json-render/yaml";

const compiler = createYamlStreamCompiler<Spec>();

// Feed chunks as they arrive from any source
const { result, newPatches } = compiler.push("root: main\n");
compiler.push("elements:\n  main:\n    type: Card\n");

// Flush remaining data at end of stream
const { result: final } = compiler.flush();

// Reset for next stream (optionally with initial state)
compiler.reset({ root: "main", elements: {} });
```

Methods: `push(chunk)`, `flush()`, `getResult()`, `getPatches()`, `reset(initial?)`

## Edit Modes (from @json-render/core)

The YAML package uses the universal edit mode system from core:

```typescript
import { buildEditInstructions, buildEditUserPrompt } from "@json-render/core";
import type { EditMode } from "@json-render/core";

// Generate edit instructions for YAML format
const instructions = buildEditInstructions({ modes: ["merge", "patch"] }, "yaml");

// Build user prompt with current spec context
const userPrompt = buildEditUserPrompt({
  prompt: "Change the title to Dashboard",
  currentSpec: spec,
  config: { modes: ["merge"] },
  format: "yaml",
  serializer: (s) => yamlStringify(s, { indent: 2 }).trimEnd(),
});
```

## Fence Constants

For custom parsing, use the exported constants:

```typescript
import {
  YAML_SPEC_FENCE,   // "```yaml-spec"
  YAML_EDIT_FENCE,   // "```yaml-edit"
  YAML_PATCH_FENCE,  // "```yaml-patch"
  DIFF_FENCE,        // "```diff"
  FENCE_CLOSE,       // "```"
} from "@json-render/yaml";
```

## Key Exports

| Export | Description |
|--------|-------------|
| `yamlPrompt` | Generate YAML system prompt from catalog |
| `createYamlTransform` | AI SDK TransformStream for YAML fences |
| `pipeYamlRender` | Convenience pipe wrapper (replaces `pipeJsonRender`) |
| `createYamlStreamCompiler` | Streaming YAML parser with patch emission |
| `YAML_SPEC_FENCE` | Fence constant for yaml-spec |
| `YAML_EDIT_FENCE` | Fence constant for yaml-edit |
| `YAML_PATCH_FENCE` | Fence constant for yaml-patch |
| `DIFF_FENCE` | Fence constant for diff |
| `FENCE_CLOSE` | Fence close constant |
| `diffToPatches` | Re-export: object diff to JSON Patch |
| `deepMergeSpec` | Re-export: RFC 7396 deep merge |

More from vercel-labs/json-render

SkillDescription
codegenCode generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing specs, or serializing props for @json-render/codegen.
devtoolsDrop-in inspector panel for any json-render app. Use when the user wants to debug a generative UI, inspect the spec tree, edit state at runtime, see dispatched actions, follow stream patches live, browse a catalog, or pick DOM elements to find their spec keys. Triggers include "add devtools", "debug json-render", "inspect the spec", "why is this element not rendering", "see the state at runtime", or requests to tap streams / capture action logs for `@json-render/devtools`.
devtools-reactReact adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-react in a React json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
devtools-solidSolidJS adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-solid in a SolidJS json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
devtools-svelteSvelte 5 adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-svelte in a Svelte json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
devtools-vueVue adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-vue in a Vue json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
directivesPre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
imageImage renderer for json-render that turns JSON specs into SVG and PNG images via Satori. Use when working with @json-render/image, generating OG images from JSON, creating social cards, or rendering AI-generated image specs.
inkInk terminal renderer for json-render that turns JSON specs into interactive terminal UIs. Use when working with @json-render/ink, building terminal UIs from JSON, creating terminal component catalogs, or rendering AI-generated specs in the terminal.
jotaiJotai adapter for json-render's StateStore interface. Use when integrating json-render with Jotai for state management via @json-render/jotai.