Json-render yaml
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.
install
source · Clone the upstream repo
git clone https://github.com/vercel-labs/json-render
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/vercel-labs/json-render "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/yaml" ~/.claude/skills/vercel-labs-json-render-yaml && rm -rf "$T"
manifest:
skills/yaml/SKILL.mdsource content
@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:
that converts YAML fences into json-render patchesTransformStream
Generating YAML Prompts
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:
(string) — Custom system message introsystem
("standalone" | "inline") — Output mode, default "standalone"mode
(string[]) — Additional rules appended to promptcustomRules
(EditMode[]) — Edit modes to document, default ["merge"]editModes
AI SDK Transform
Use
pipeYamlRender as a drop-in replacement for pipeJsonRender:
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:
pipeYamlRender(result.toUIMessageStream(), { previousSpec: currentSpec, });
The transform recognizes four fence types:
— Full spec, parsed progressively line-by-lineyaml-spec
— Partial YAML deep-merged with current spec (RFC 7396)yaml-edit
— RFC 6902 JSON Patch linesyaml-patch
— Unified diff applied to serialized specdiff
Streaming Parser (Low-Level)
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:
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:
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 |
|---|---|
| Generate YAML system prompt from catalog |
| AI SDK TransformStream for YAML fences |
| Convenience pipe wrapper (replaces ) |
| Streaming YAML parser with patch emission |
| Fence constant for yaml-spec |
| Fence constant for yaml-edit |
| Fence constant for yaml-patch |
| Fence constant for diff |
| Fence close constant |
| Re-export: object diff to JSON Patch |
| Re-export: RFC 7396 deep merge |