Deterministic charts for AI agents. Same JSON spec → same SVG bytes, every platform, every run. Built so an LLM can author, diff, and patch charts the way a developer authors code.
Built by AI. Maintained by AI. This repo is triaged, reviewed, and merged by Cowork (an instance of Claude). See the live maintenance dashboard, the agent-facing docs (
AGENTS.md), or the canonical two-agents-on-a-chart demo.
One sentence to Claude → glyph_story MCP call → this animated SVG.
No JS, no CDN. Deterministic. Same bytes a year from now.
🎨 Try the playground · 📚 Learn in 30 minutes · 🤖 Use with Claude · 💬 Discussions
🚀 0.3.0 release essay · 🖼️ Gallery · 📝 What it's for (essay) · 🤝 Two-agents demo · 🔭 Extended cases · ✨ Particles tutorial
- LLM agents that draw charts. Claude, ChatGPT, Gemini and any MCP client can call 53 verbs (
glyph_render,glyph_describe,glyph_audit_spec,glyph_seal,glyph_story, …) — no JS code generation, no client-side library to ship. - CI-stable visual regression tests. Snapshot a chart's bytes; assert on them. Glyph is byte-identical across Ubuntu / macOS / Windows × Node 20 / 22.
- Provenance-auditable analytics. Every rendered SVG embeds a SHA-256 seal over (spec, rows, schema). Anyone can recompute and verify.
- Charts that explain themselves. The structured
Explanationenvelope (M2) lets an agent chain follow-up MCP calls without re-parsing prose. - Kid-persona math viz.
glyph_story({intent:"sine wave", audience:"kid"})composes a multi-scene animated SVG with bouncing dots and captions. Seedocs/LEARN.md. - Embedded analytics that need SQL. DuckDB lives inside the renderer; transforms live in the spec.
- High-frequency interactive dashboards with millions of points. Glyph's renderer rounds to fixed SVG precision; for hardware-accelerated WebGL paths use Three.js / Plotly.
- Drop-in Plotly / Vega-Lite replacement. The grammar is similar but the spec format isn't compatible. You can translate Vega-Lite → Glyph via
vegaLiteToGlyph, but it's not a 1:1 swap. - Print-quality typography. Headless SVG with system fonts. If you need kerning-perfect typesetting, render Glyph SVGs and post-process with a PDF tool.
claude mcp add glyph -- npx -y @glyph/mcpWorks identically with Cursor, Codex CLI, Copilot CLI, Gemini CLI, or any MCP client. Then ask:
Use
glyph_storyto show me a sine wave for an 8-year-old. Save the SVG to./sine.svg.
Open sine.svg in any browser. Curve draws, dot bounces, peak annotation lands — one MCP call, deterministic, self-contained. Same artifact as the hero above.
npm install @glyph/core @glyph/duckdbimport { compileSpec, renderSvg } from "@glyph/core";
import { createDuckDBEngine, materializeSpec } from "@glyph/duckdb";
const engine = await createDuckDBEngine();
const m = await materializeSpec(engine, {
data: { source: "rides.csv", format: "csv" },
layers: [{ mark: "bar", encoding: { x: "hour", y: "rides" } }],
});
const scene = compileSpec({
spec: m.effectiveSpec,
rows: m.result.rows,
schema: m.handle.schema,
});
const svg = renderSvg(scene); // byte-identical across platforms- 🎨 Playground — paste a CSV, edit a spec, share via URL. Browser-only.
- 🧒 Kid landing page — see Joy of Math demos including two interactive three.js wow demos.
- ✨ Joy of Math wow page — nine interactive demos: six parametric curves (Lissajous, hypotrochoid, curlicue, Archimedean spiral, butterfly, gravity-lensing) plus three fluid + PDE simulations (particle flow field, 2D wave-equation ripples, Gray-Scott reaction-diffusion / Turing patterns). Drag sliders, click the wave-equation canvas to drop ripples.
- 📚 30-minute learn guide — 7 hands-on sections, three of them no-install.
Every image below is a real fixture in this repo, locked at byte-identity in CI. Click for the raw animated SVG.
For 15 more demos — streamgraph morph, racing bars, choropleth, force graph, treemap, sunburst, contour, geo overlay — see
site/index.html(single static HTML file, no build).
Eight hand-crafted showcases of what one English prompt + an AI agent + Glyph produce together. Each page picks a subject anyone can recognize, walks the reader through prompt → JSON spec → byte-locked SVG → animated page, and ends with prompt templates you can adapt for your own ideas.
Gallery: seanhanca.github.io/glyph/math/life-in-glyph.html
Each page ends with four prompt templates ("your turn — prompts to try") across different domains, so you can adapt the pattern to your own subject — a zebra's stripes, a pine cone's spirals, a different mission, a different oscillator, a Stirling engine, a tide-predicting machine, a robot arm.
┌─────────────────┐
│ JSON spec │ ← agent or developer writes this
└────────┬────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
materializer compiler auditor
(DuckDB) (pure fn) (11 rules)
│ │ │
└───────────────┼───────────────┘
▼
┌─────────────────┐
│ scene graph │ ← immutable IR
└────────┬────────┘
│
┌────────┴────────┐
▼ ▼
SVG (server) Canvas (browser)
│
└─→ + SHA-256 provenance seal
+ structured Explanation envelope
+ 8 audit findings (when applicable)
Every box is a pure function: same input, same output, no global state. The MCP server wraps the pipeline in an addressable handle protocol (gdf://) so handles flow between processes with full lineage. canonicalStringify clamps floating-point numbers to 14 significant digits before hashing, so Math.sin libm drift across platforms doesn't break determinism.
| Read this | If you want to |
|---|---|
docs/LEARN.md |
Learn Glyph hands-on in 30 minutes (recommended starting point) |
docs/MATH.md |
Build math + physics visualizations |
CHANGELOG.md |
See what's in the latest release |
CONTRIBUTING.md |
Send your first PR (four difficulty-ranked paths) |
packages/core/src/spec/types.ts |
Read the canonical spec format (TypeScript) |
packages/core/dist/spec.schema.json |
JSON Schema for editor autocomplete |
site/index.html |
The full interactive site — playground, 8 demos, 16-row comparison, capability matrix |
INNOVATION.md · D3-COMPARISON.md · AUDIT.md · ROADMAP.md |
Deep reference docs |
| D3 | Vega-Lite | Plotly | Tableau | Power BI | Glyph | |
|---|---|---|---|---|---|---|
| Deterministic byte-stable output | no | partial | no | no | no | yes |
| Embedded SQL engine | no | no | no | proprietary | proprietary | DuckDB |
| MCP server (agent-native) | no | no | no | no | no | 53 verbs |
| Built-in chart auditor | no | no | no | no | no | 11 rules |
| Cryptographic provenance seal | no | no | no | no | no | SHA-256 |
| Spec diff / patch (RFC 6902) | no | no | no | no | no | yes |
| Animation as a declarative spec | no | no | partial | partial | partial | 5 kinds |
| License | BSD-3 | BSD-3 | MIT | Proprietary | Proprietary | Apache 2.0 |
Full 16-row matrix at site/index.html#compare.
| Package | What it does | Install |
|---|---|---|
@glyph/core |
Compiler, scene graph, SVG renderer | npm i @glyph/core |
@glyph/duckdb |
DuckDB-backed materializer | npm i @glyph/duckdb |
@glyph/mcp |
MCP server, 53 verbs | npx -y @glyph/mcp |
@glyph/live |
Browser hydration: sliders, hover, brush, zoom | npm i @glyph/live |
@glyph/preview-server |
Local preview for Cursor / Jupyter | npm i @glyph/preview-server |
@glyph/cli |
glyph render / check / diff |
npm i -g @glyph/cli (private — not yet released) |
@glyph/canvas |
Canvas renderer (same scene graph as SVG) | (private — not yet released) |
- v0.3.0 on
main(CHANGELOG.md) - 1022 tests passing on Ubuntu / macOS / Windows × Node 20 / 22
- 53 MCP verbs, 24 mark types, 16 audit rules, 4 data shapes
- 4 brand presets (
light,dark,playground,3b1b), 5 animation kinds - 0 telemetry, 0 phone-home, runs entirely on your machine
- Node ≥ 20
- For the DuckDB engine: macOS (Apple Silicon or Intel), Linux x64, or Windows x64
- Discussions — Q&A, recipe ideas, gallery
- Issues — four structured templates (bug, feature, MCP verb idea, recipe idea)
- CONTRIBUTING.md — four contributor paths, sorted by difficulty
- CODE_OF_CONDUCT.md — Contributor Covenant v2.1
- SECURITY.md — vulnerability disclosure policy
If the demos above made you smile, ⭐ star the repo — it's how new contributors find us.
Apache 2.0. No telemetry. No phone-home. Self-hostable. Audit-safe by default.