{"id":50586062,"url":"https://github.com/tool3/dvd","last_synced_at":"2026-06-05T06:30:27.264Z","repository":{"id":355853861,"uuid":"1172864966","full_name":"tool3/dvd","owner":"tool3","description":"Create simple animated SVGs from your terminal","archived":false,"fork":false,"pushed_at":"2026-05-13T20:17:59.000Z","size":20888,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-13T22:22:41.472Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tool3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-04T19:11:32.000Z","updated_at":"2026-05-13T20:18:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tool3/dvd","commit_stats":null,"previous_names":["tool3/dvd"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/tool3/dvd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tool3%2Fdvd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tool3%2Fdvd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tool3%2Fdvd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tool3%2Fdvd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tool3","download_url":"https://codeload.github.com/tool3/dvd/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tool3%2Fdvd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33932048,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-05T06:30:25.752Z","updated_at":"2026-06-05T06:30:27.255Z","avatar_url":"https://github.com/tool3.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/svgs/low-level-api.svg\" alt=\"dvdrw — animated SVG terminal recordings, programmatic\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eGenerate animated SVG terminal recordings from code.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/dvdrw\"\u003e\u003cimg src=\"https://img.shields.io/badge/npm-v10-blue\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/dvdrw\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/dvdrw\" alt=\"npm downloads\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/tool3/dvd/blob/master/LICENSE.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-orange\" alt=\"license\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/tool3/dvd-cli\"\u003e\u003cimg src=\"https://img.shields.io/badge/cli-dvd--cli-7c5fff\" alt=\"cli\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n`dvdrw` is the Node library behind [`dvd-cli`](https://github.com/tool3/dvd-cli) — call it from your own code, your build pipeline, or your service. Output is a single self-contained animated SVG. No ffmpeg, no headless browser, no shelling out.\n\n```bash\nnpm install dvdrw\n```\n\n```typescript\nimport dvd from 'dvdrw';\n\nconst { svg } = await dvd(`\n  Type \"echo hello world\"\n  Enter\n  Sleep 800ms\n`, { theme: 'dracula', template: 'macos' });\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/quick-start.svg\" alt=\"quick start\" /\u003e\n\u003c/p\u003e\n\n---\n\n## Contents\n\n- [Why the library?](#why-the-library)\n- [Inputs](#inputs)\n  - [CD script string](#1-cd-script-string)\n  - [Programmatic steps](#2-programmatic-steps)\n  - [Raw terminal output](#3-raw-terminal-output)\n  - [Pre-parsed script](#4-pre-parsed-script)\n- [Themes](#themes)\n- [Templates](#templates)\n- [Loop styles](#loop-styles)\n- [Branded output](#branded-output)\n- [Progress tracking](#progress-tracking)\n- [Low-level API](#low-level-api)\n- [Rendering modes](#rendering-modes-filmstrip-vs-smil)\n- [Options reference](#options-reference)\n- [Steps reference](#steps-reference)\n- [Comparison](#comparison)\n- [Related](#related)\n\n---\n\n## Why the library?\n\nThe CLI is great when you have a `.cd` script in a file. The library is for everything else:\n\n- **Programmatic content** — render the output of a real test run, a real deploy, or a real benchmark, with frames built from runtime data.\n- **Raw stdout capture** — feed any ANSI byte stream straight in (`{ raw }`). Spinners, progress bars, `chartscii`, `lolcat`, anything that animates on the terminal.\n- **Build-pipeline integration** — fully `async`, optional `onProgress` callback, no temp files, no subprocesses by default.\n- **Embeddable** — drop into a docs generator, a service, an Electron app, a serverless function. The output is a string.\n- **Composable** — the parser, terminal emulator, coalescer, emitter and animator are all exported and usable independently.\n\nIf you want a single command on the CLI that takes a `.cd` file and writes a `.svg`, use [`dvd-cli`](https://github.com/tool3/dvd-cli). If you want to call into the engine, you're in the right place.\n\n---\n\n## Inputs\n\n`dvd(input, options)` accepts four input shapes. Pick whichever matches the data you already have.\n\n### 1. CD script string\n\nThe fastest path. Same syntax as `dvd-cli`, just inlined.\n\n```typescript\nconst { svg } = await dvd(`\n  Type \"npm install dvdrw\"\n  Sleep 400ms\n  Enter\n  Sleep 800ms\n`, { theme: 'dracula', template: 'macos', title: 'quick-start' });\n```\n\n### 2. Programmatic steps\n\nWhen the content of your animation is computed at runtime — a generated test report, a stream of deploy events, a templated demo — skip the script and pass an array.\n\n```typescript\n// Each Type+Enter is sent through a real shell, so wrap any styled output\n// in `echo -e \"...\"` rather than typing raw ANSI as a command.\nconst steps = [\n  { type: 'Type', text: 'echo -e \"\\\\x1b[2m$\\\\x1b[0m npm test\"' },\n  { type: 'Key', key: 'Enter' },\n  { type: 'Sleep', duration: 600 },\n  ...tests.flatMap((t) =\u003e [\n    { type: 'Type', text: `echo -e \"\\\\x1b[32m  ✓\\\\x1b[0m ${t.name} \\\\x1b[2m(${t.ms}ms)\\\\x1b[0m\"` },\n    { type: 'Key', key: 'Enter' },\n    { type: 'Sleep', duration: 200 },\n  ]),\n];\n\nconst { svg } = await dvd(steps, { theme: 'tokyoNight', template: 'macos', title: 'test runner' });\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/programmatic-steps.svg\" alt=\"programmatic test runner output\" /\u003e\n\u003c/p\u003e\n\n\u003e Full source: [`examples/02-programmatic-steps.ts`](examples/02-programmatic-steps.ts)\n\n### 3. Raw terminal output\n\nCapture stdout from any command and hand the bytes over. dvd auto-detects the animation pattern (cursor reset, terminal reset, clear-line, cursor-up) and splits into frames automatically.\n\n```typescript\nimport dvd from 'dvdrw';\nimport { spawnSync } from 'node:child_process';\n\nconst r = spawnSync('myscript.sh', { encoding: 'buffer' });\nconst raw = r.stdout.toString('binary');\n\nconst { svg } = await dvd({ raw, totalDuration: 2400 }, {\n  theme: 'catppuccinMocha',\n  template: 'macos',\n  title: 'spinner capture',\n});\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/raw-output.svg\" alt=\"captured spinner output\" /\u003e\n\u003c/p\u003e\n\n\u003e Full source: [`examples/03-raw-output.ts`](examples/03-raw-output.ts)\n\n### 4. Pre-parsed script\n\nIf you've already parsed a CD script (e.g., for validation or transformation), pass the AST directly:\n\n```typescript\nimport dvd, { parseCDScript } from 'dvdrw';\n\nconst script = parseCDScript(scriptText);\n// ...mutate, validate, splice frames...\nconst { svg } = await dvd({ script }, { theme: 'nord' });\n```\n\n---\n\n## Themes\n\n37 built-in themes, all exported from `themes`. Pass by name or as a full `Theme` object.\n\n```typescript\nawait dvd(script, { theme: 'tokyoNight' });\n```\n\n\u003ctable\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003edracula\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/dracula.svg\" alt=\"dracula\" /\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003etokyoNight\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/tokyoNight.svg\" alt=\"tokyoNight\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003ecatppuccinMocha\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/catppuccinMocha.svg\" alt=\"catppuccinMocha\" /\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003enord\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/nord.svg\" alt=\"nord\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003egruvboxDark\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/gruvboxDark.svg\" alt=\"gruvboxDark\" /\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003emonokai\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/monokai.svg\" alt=\"monokai\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003eoneDark\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/oneDark.svg\" alt=\"oneDark\" /\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003esynthwave84\u003c/strong\u003e\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/themes/synthwave84.svg\" alt=\"synthwave84\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\nThe full list: `a11yDark`, `base16Dark`, `base16Light`, `blackboard`, `catppuccinMocha`, `cobalt`, `dark`, `dracula`, `draculaPro`, `duotoneDark`, `githubDark`, `githubLight`, `gruvboxDark`, `gruvboxLight`, `hopscotch`, `lucario`, `material`, `monokai`, `night3024`, `nord`, `oceanicNext`, `oneDark`, `oneLight`, `pandaSyntax`, `paraisoDark`, `seti`, `shadesOfPurple`, `solarizedDark`, `solarizedLight`, `synthwave84`, `terminal`, `tokyoNight`, `twilight`, `verminal`, `vscode`, `yeti`, `zenburn`.\n\nFor custom palettes, pass a `Theme` object directly:\n\n```typescript\nimport dvd, { type Theme } from 'dvdrw';\n\nconst retroGreen: Theme = {\n  name: 'retro',\n  background: '#0a0a0a',\n  foreground: '#00ff00',\n  cursor: '#00ff00',\n  // ...the 16 ANSI colors\n};\n\nawait dvd(script, { theme: retroGreen });\n```\n\n\u003e Source: [`examples/04-themes-gallery.ts`](examples/04-themes-gallery.ts)\n\n---\n\n## Templates\n\nWindow chrome — `macos` / `windows` / `minimal`.\n\n\u003ctable\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003emacos\u003c/strong\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003ewindows\u003c/strong\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003eminimal\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/templates/macos.svg\" alt=\"macos template\" /\u003e\u003c/td\u003e\n  \u003ctd\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/templates/windows.svg\" alt=\"windows template\" /\u003e\u003c/td\u003e\n  \u003ctd\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/templates/minimal.svg\" alt=\"minimal template\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003e Source: [`examples/09-templates.ts`](examples/09-templates.ts)\n\n---\n\n## Loop styles\n\nAnimations loop by default. Choose how the loop behaves at the boundary:\n\n```typescript\nawait dvd(script, {\n  loopStyle: 'reverse',  // 'loop' | 'reverse' | 'rewind' | 'fade'\n  loopPause: 600,\n  rewindSpeed: 6,        // for 'rewind'\n  fadeDuration: 1200,    // for 'fade'\n});\n```\n\n\u003ctable\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003eloop\u003c/strong\u003e — restart from frame 0\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/loop-styles/loop.svg\" alt=\"loop style: loop\" /\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003ereverse\u003c/strong\u003e — play forward then back\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/loop-styles/reverse.svg\" alt=\"loop style: reverse\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003erewind\u003c/strong\u003e — fast reverse like rewinding tape\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/loop-styles/rewind.svg\" alt=\"loop style: rewind\" /\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003cstrong\u003efade\u003c/strong\u003e — fade to black, fade back in\u003cbr\u003e\u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/loop-styles/fade.svg\" alt=\"loop style: fade\" /\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003e Source: [`examples/05-loop-styles.ts`](examples/05-loop-styles.ts)\n\n---\n\n## Branded output\n\nGradient backgrounds, watermarks, custom borders — for docs sites and landing pages where the SVG carries product weight.\n\n```typescript\nconst { svg } = await dvd(script, {\n  theme: 'tokyoNight',\n  template: 'macos',\n  background: 'gradient(#7c5fff, #ff6ec7:diagonal)',\n  backgroundPadding: 48,\n  borderRadius: 12,\n  watermark: 'made with dvd',\n});\n```\n\nBackgrounds accept solid colors (`#1a1a2e`) or gradients in the form `gradient(\u003ccolor\u003e, \u003ccolor\u003e[:vertical|horizontal|diagonal])` with as many stops as you need.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/branding.svg\" alt=\"branded output\" /\u003e\n\u003c/p\u003e\n\n\u003e Source: [`examples/06-branding.ts`](examples/06-branding.ts)\n\n---\n\n## Progress tracking\n\nWire dvd into your build pipeline or TUI. The `onProgress` callback fires for every step the executor runs.\n\n```typescript\nawait dvd(script, {\n  onProgress: (current, total, description) =\u003e {\n    const pct = Math.round((current / total) * 100);\n    process.stdout.write(`\\r[${pct}%] ${description ?? ''}`);\n  },\n});\n```\n\nThe returned result also carries metadata — frame count, total duration, effective FPS — for logging and CI annotations:\n\n```typescript\nconst result = await dvd(script);\nconsole.log(result.metadata); // { duration: 2118, frameCount: 33, fps: 15.6 }\n```\n\n\u003e Source: [`examples/07-progress.ts`](examples/07-progress.ts)\n\n---\n\n## Low-level API\n\nSkip the executor when you want to render arbitrary terminal state directly — for static badges, dashboards, CI annotations, or content that doesn't fit the script model.\n\n```typescript\nimport { coalesce, createGridState, emit, processInput, themes } from 'dvdrw';\n\nconst fontSize = 16;\nconst theme = themes.draculaPro;\n\nlet state = createGridState(44, 9);\nstate = processInput(state, '\\x1b[1;38;5;213m  dvdrw\\x1b[0m · terminal recordings as svg');\n\nconst spans = coalesce(state, theme);\n\nconst { svg } = emit(spans, state.cursor, false, {\n  theme,\n  template: 'minimal',\n  width: 460,\n  height: 240,\n  fontSize,\n  lineHeight: fontSize * 1.4,\n  charWidth: fontSize * 0.6,\n  padding: 16,\n});\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/tool3/dvd/blob/master/examples/svgs/low-level-api.svg\" alt=\"low-level API output\" /\u003e\n\u003c/p\u003e\n\nThe exposed building blocks:\n\n| Module | Symbols |\n|---|---|\n| Terminal emulator | `createGridState`, `processInput`, `applyCommand`, `applyCommands`, `parseInput` |\n| Text processing | `coalesce` |\n| Emission | `emit`, `emitAnimated`, `emitFilmstripAnimated` |\n| Animation | `createAnimatedSVG`, `createFilmstripSVG`, `optimizeSvg` |\n| Raw output | `processRawOutput`, `detectAnimationType`, `splitIntoFrames` |\n| Cast files | `parseCastFile`, `RecordingPlayer`, `generateFramesFromRecording` |\n| Script parsing | `parseCDScript`, `CDParseError` |\n| Executor | `CDExecutor` |\n\n\u003e Source: [`examples/08-low-level-api.ts`](examples/08-low-level-api.ts)\n\n---\n\n## Rendering modes: filmstrip vs SMIL\n\nTwo animation engines are available. The default (filmstrip) is what you almost always want.\n\n| | **Filmstrip** (default) | **SMIL** (`smil: true`) |\n|---|---|---|\n| Engine | CSS `@keyframes` over a deduped row pool | Native SVG `\u003canimate\u003e` per frame |\n| File size | Smaller — scales with *unique rows*, not total frames | Larger — scales with total frames |\n| Best for | README embeds, docs, long recordings, mostly-static content | Short animations, high-FPS smoothness on iOS Safari / 120Hz |\n\n```typescript\nawait dvd(script, { smil: true });\n```\n\n---\n\n## Options reference\n\n```typescript\nconst { svg, frames, frameData, metadata } = await dvd(input, {\n  // Window chrome\n  theme,                  // Theme name (string) or Theme object — default 'dark'\n  template,               // 'macos' | 'windows' | 'minimal' — default 'macos'\n  title,                  // window title text\n  watermark,              // string or SVG markup\n\n  // Dimensions\n  width, height,          // omit for auto-sizing from script content\n  fontSize,               // default 14\n  lineHeight,             // multiplier — default 1.4\n  letterSpacing,\n  fontFamily,\n  padding,                // default 16\n\n  // Borders\n  borderRadius,           // default 8\n  borderColor, borderWidth,\n\n  // Background (outside the terminal window)\n  background,             // '#hex' or 'gradient(#a, #b[:horizontal|vertical|diagonal])'\n  backgroundPadding,\n  backgroundRadius,\n\n  // Header / footer\n  headerHeight, headerBackground, headerBorder,\n  headerBorderColor, headerBorderWidth,\n  footerHeight, footerBackground, footerBorder,\n  footerBorderColor, footerBorderWidth,\n\n  // Cursor\n  cursorStyle,            // 'block' | 'bar' | 'underline'\n  cursorColor,\n  cursorBlink,            // default false\n\n  // Animation\n  fps,\n  loop,                   // default true\n  loopStyle,              // 'loop' | 'reverse' | 'rewind' | 'fade'\n  loopPause,              // ms between cycles\n  pauseAtEnd,             // ms hold on last frame — default 1000\n  fadeDuration,           // ms for 'fade' style — default 1500\n  rewindSpeed,            // multiplier for 'rewind' — default 5\n  playbackSpeed,          // 1 = normal, 2 = 2x, 0.5 = half speed\n\n  // Renderer\n  smil,                   // false = filmstrip (default), true = SMIL\n  optimize,               // SVGO post-pass — default true\n  customGlyphs,           // box-drawing as geometric shapes — default true\n\n  // Callbacks\n  onFrame,                // (frame: TerminalFrame) =\u003e void\n  onProgress,             // (current, total, description?) =\u003e void\n});\n```\n\nThe result:\n\n```typescript\nresult.svg                  // animated SVG string\nresult.metadata.duration    // total ms\nresult.metadata.frameCount  // number of frames\nresult.metadata.fps         // effective fps\nresult.frames               // TerminalFrame[]\nresult.frameData            // FrameData[] — raw row data, useful for custom emitters\n```\n\n---\n\n## Steps reference\n\nWhen using the programmatic-steps input, each entry conforms to one of these shapes:\n\n| Type | Fields | Example |\n|---|---|---|\n| `Type` | `text`, optional `speed` (ms/char) | `{ type: 'Type', text: 'hello', speed: 50 }` |\n| `Key` | `key` | `{ type: 'Key', key: 'Enter' }` |\n| `Sleep` | `duration` (ms) | `{ type: 'Sleep', duration: 1000 }` |\n| `Shortcut` | `key` + modifier flags | `{ type: 'Shortcut', ctrl: true, key: 'c' }` |\n| `Screenshot` | `path` | `{ type: 'Screenshot', path: 'frame.svg' }` |\n| `Copy` / `Paste` | `text` (Copy only) | `{ type: 'Copy', text: 'hi' }` |\n| `Set` | `setting`, `value` | `{ type: 'Set', setting: 'Theme', value: 'dracula' }` |\n| `Env` | `key`, `value` | `{ type: 'Env', key: 'NODE_ENV', value: 'prod' }` |\n\nKeys: `Enter`, `Backspace`, `Tab`, `Space`, `Left`, `Right`, `Up`, `Down`.\n\n---\n\n## Comparison\n\n|                   |     dvdrw      |     VHS      |  asciinema   |\n| ----------------- | :------------: | :----------: | :----------: |\n| Output            |      SVG       |   GIF / MP4  |   asciicast  |\n| Native API        | TypeScript lib |     CLI      | JSON + player |\n| Dependencies      |      none      | ffmpeg, ttyd | player embed |\n| Scalable          |      yes       |      no      |     yes      |\n| GitHub README     |    perfect     |    works     | embed only   |\n| Editable          |   yes (XML)    |      no      | yes (JSON)   |\n| Offline           |      yes       |     yes      |      no      |\n| Loop styles       |    4 modes     |    basic     |    basic     |\n| Programmatic      |      yes       |   limited    |     yes      |\n\n---\n\n## Examples\n\nAll runnable. Each writes its SVG into `examples/svgs/`.\n\n```bash\nnpx ts-node -P tsconfig.dev.json examples/01-quick-start.ts\nnpx ts-node -P tsconfig.dev.json examples/02-programmatic-steps.ts\nnpx ts-node -P tsconfig.dev.json examples/03-raw-output.ts\nnpx ts-node -P tsconfig.dev.json examples/04-themes-gallery.ts\nnpx ts-node -P tsconfig.dev.json examples/05-loop-styles.ts\nnpx ts-node -P tsconfig.dev.json examples/06-branding.ts\nnpx ts-node -P tsconfig.dev.json examples/07-progress.ts\nnpx ts-node -P tsconfig.dev.json examples/08-low-level-api.ts\nnpx ts-node -P tsconfig.dev.json examples/09-templates.ts\n\n# or render them all in one go:\nnpx ts-node -P tsconfig.dev.json examples/10-render-all.ts\n```\n\n---\n\n## Related\n\n- [`dvd-cli`](https://github.com/tool3/dvd-cli) — the CLI front-end (`.cd` scripts, pipe mode, `rec` / `render` sub-commands)\n- [`shellfie`](https://github.com/tool3/shellfie) — terminal screenshots in code\n- [`shellfie-cli`](https://github.com/tool3/shellfie-cli) — terminal screenshots CLI\n- [`shellfied`](https://github.com/tool3/shellfied) — terminal screenshots web service\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftool3%2Fdvd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftool3%2Fdvd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftool3%2Fdvd/lists"}