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.
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
- LLM agents that draw charts. Claude, ChatGPT, Gemini and any MCP client can call 52 verbs (
glyph_render,glyph_describe,glyph_audit_spec,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
data.shape: "function" Β· NASA Artemis I, 25 days, three phasesPrompt: "Draw me NASA's Artemis I Orion spacecraft journey to the Moon and back. Show the outbound transit, a wide retrograde orbit, and the return arc. Beautiful for a 5-year-old, meaningful for a 70-year-old." |
β€οΈ A heartbeat at restdata.shape: "trajectory" Β· FitzHugh-Nagumo relaxation oscillator (1961)Prompt: "Draw me a heartbeat β a resting human heart at 60 BPM. Use FitzHugh-Nagumo so the trace has the real spike-and-recover rhythm. Beautiful for a child, meaningful for a grandparent." |
data.shape: "pde-solve" Β· Gray-Scott reaction-diffusion Β· Turing 1952, Kipling 1902Prompt: "Draw me how the leopard got his spots. Use Gray-Scott reaction-diffusion at F = k = 0.062. Start from a single seed, run 400 steps, let the pattern emerge." |
data.shape: "recurrence" Β· Vogel's golden-angle phyllotaxis (1979)Prompt: "Draw me how a sunflower packs its seeds. Each seed n at radius βn, angle n Γ 137.5Β° (the golden angle). 200 seeds. Show why this angle and only this angle works." |
π§ Watt's steam enginedata.shape: "function" Β· slider-crank kinematics (1769) Β· pencil/parchment stylePrompt: "Draw me James Watt's steam engine β the slider-crank mechanism that converts piston motion into rotation. Pencil-sketch style. Beautiful enough for a child to follow the crank; technical enough for a mechanical engineer to recognize the asymmetric power stroke." |
data.shape: "trajectory" Β· damped harmonic oscillator (1656)Prompt: "Draw me Christiaan Huygens' pendulum clock. 2D trajectory ODE: dΞΈ/dt = Ο, dΟ/dt = β(g/L)Β·ΞΈ β Ξ³Β·Ο, with Ξ³ = 0.02. Pencil-sketch style. Beautiful enough for a child to count the swings; deep enough that a horologist recognizes the decay envelope." |
π Wankel rotary enginedata.shape: "function" Β· epitrochoidal housing (Felix Wankel, 1957)Prompt: "Draw me a Wankel rotary engine housing. Parametric function with a 1:3 frequency ratio: x(t) = RΒ·cos(t) + eΒ·cos(3t), y(t) = RΒ·sin(t) + eΒ·sin(3t). Pencil-sketch style. A child should see the three lobes; an engineer should recognize why a triangular rotor exactly fits." |
βοΈ The Antikythera Mechanismdata.shape: "function" Β· compound epicycle (~150 BCE)Prompt: "Draw me the Antikythera Mechanism's Moon-pointer output. Compound epicycle: x(t) = RβΒ·cos(t) + RβΒ·cos(13t), with Rβ = 5 deferent + Rβ = 1.2 epicycle. Pencil-sketch style. A child should see the flower-pattern; a historian should recognize the Saros 223:235 ratio." |
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 | 52 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, 52 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.2.0 on
main(CHANGELOG.md) - 819 tests passing on Ubuntu / macOS / Windows Γ Node 20 / 22
- 52 MCP verbs, 21 mark types, 11 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.