Skip to content

seanhanca/glyph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

224 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Glyph

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.

License: Apache 2.0 Release Tests Node CI No telemetry

Sine wave story composed by glyph_story β€” animated SVG, same bytes Claude returns

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


What Glyph is best for

  • 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 Explanation envelope (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. See docs/LEARN.md.
  • Embedded analytics that need SQL. DuckDB lives inside the renderer; transforms live in the spec.

What Glyph is not for

  • 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.

Get started

Use it from an LLM agent

claude mcp add glyph -- npx -y @glyph/mcp

Works identically with Cursor, Codex CLI, Copilot CLI, Gemini CLI, or any MCP client. Then ask:

Use glyph_story to 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.

Use it as a TypeScript library

npm install @glyph/core @glyph/duckdb
import { 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

Try it without installing

  • 🎨 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.

See it in action

Every image below is a real fixture in this repo, locked at byte-identity in CI. Click for the raw animated SVG.

Circle β†’ 2Ο€r unwrap (multi-scene timeline)
Multi-scene timeline
Circle β†’ radius β†’ 2Ο€r unwrap
Sine wave with traveling dot (SMIL animateMotion)
Traveler mark
SMIL animateMotion + comet trail
Archimedean spiral drawing itself
Pen-draw animation
Archimedean spiral, dash-offset trick
Vector field streamlines via RK4
Streamlines
RK4-integrated vector field
Cubic Bezier with de Casteljau construction
Bezier construction
de Casteljau overlay at t=0.5
Lissajous curve
Parametric curve
Lissajous: sin(3t), cos(2t)
Peak callout annotation
Annotation mark
Labeled arrow with auto-anchor
3Blue1Brown chalkboard theme
BrandKit preset
theme: "3b1b" chalkboard
Playground kid theme
BrandKit preset
theme: "playground" kid-bright

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).


Life in Glyph

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

Life β€” biology, physics, the cosmos

Orion's journey β€” Earth, Moon, spacecraft path data.shape: "function" Β· NASA Artemis I, 25 days, three phases

Prompt: "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."
Heartbeat β€” FitzHugh-Nagumo trace

❀️ A heartbeat at rest

data.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."
Leopard's spots β€” Gray-Scott reaction-diffusion data.shape: "pde-solve" Β· Gray-Scott reaction-diffusion Β· Turing 1952, Kipling 1902

Prompt: "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."
Sunflower seeds β€” golden-angle phyllotaxis 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."

Machines of Wonder β€” what humans built

Slider-crank piston-position curve data.shape: "function" Β· slider-crank kinematics (1769) Β· pencil/parchment style

Prompt: "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."
Damped pendulum oscillation 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 epitrochoid housing curve data.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."
Antikythera compound-epicycle Moon trace data.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.


How it works

              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   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.


Documentation

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

Comparison

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.


Packages

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)

Status

  • 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

Requirements

  • Node β‰₯ 20
  • For the DuckDB engine: macOS (Apple Silicon or Intel), Linux x64, or Windows x64

Community

If the demos above made you smile, ⭐ star the repo β€” it's how new contributors find us.


License

Apache 2.0. No telemetry. No phone-home. Self-hostable. Audit-safe by default.