Open source visualization build tool for your data pipeline.
Ship charts from the same pipeline as your data.
Define charts in SQL, compose dashboards in YAML, publish anywhere.
Install · Quickstart · How it works · CLI · Examples · Docs
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ dbt project │ │ glyf sources │ │ glyf build │
├──────────────────────┤ ├──────────────────────┤ ├──────────────────────┤
│ models/*.sql │ │ charts *.ggsql │ │ resolve ref() │
│ target/manifest.json │──▶│ dashboards *.yml │──▶│ execute SQL │
│ warehouse relations │ │ macros *.py │ │ render Altair │
└──────────────────────┘ └──────────────────────┘ └───────────┬──────────┘
│
┌─────────────────────────┬───────────────────────┬───────────┘
▼ ▼ ▼
site/index.html charts/*.png *.svg export --zip
static dashboard chart artifacts zip for CI
Every stage of the modern data stack has declarative, version-controlled, testable artifacts. Every stage except visualization.
Your models are versioned. Your jobs are automated. Your data quality is tested. Visualization is still the last artifact outside the pipeline.
- Dashboards live outside the workflow. Your dbt models are in Git. Your charts are usually configured in a browser, stored elsewhere, and maintained by whoever last touched the UI.
- Columns rename, charts break silently. When dbt models change, dashboard failures show up late. glyf moves chart definitions into a build step that validates earlier.
- Publishing should not require a vendor. For internal portals and product dashboards, rendered HTML and chart assets are usually enough.
glyf is artifact-driven, not dbt-runtime-driven: run dbt first, then run glyf against the resulting artifacts and relations.
glyf is published on PyPI as glyf-core. The package installs the glyf
command and the glyf Python module; only the distribution name differs.
uv tool install glyf-core
glyf --versionOther ways to install — one-line script, Homebrew, pipx, pip, offline
One-line script (macOS and Linux). Installs uv first if it is missing,
never uses sudo, and accepts --update, --version X, and --help:
curl -fsSL https://raw.githubusercontent.com/glyf-data/glyf/main/install.sh | shHomebrew. brew trust is required, not optional — Homebrew 6.0 refuses to
load formulae from untrusted third-party taps:
brew tap glyf-data/glyf
brew trust --tap glyf-data/glyf
brew install glyfpipx or pip. Prefer uv or pipx for a CLI tool; use pip when you want
glyf inside an existing project virtualenv, next to dbt-core:
pipx install glyf-core
python -m pip install glyf-coreOffline or air-gapped. Every release
ships platform wheels, an sdist, and a checksums.txt:
sha256sum --check --ignore-missing checksums.txt
uv tool install ./glyf_core-<version>-cp311-abi3-<platform>.whlPrebuilt wheels cover Linux (x86_64, aarch64), macOS (Intel, Apple Silicon),
and Windows (x86_64). They target Python 3.11+ through the stable ABI, so one
wheel per platform covers every supported Python version and no Rust toolchain
is needed. Upgrade with uv tool upgrade glyf-core.
In an existing dbt project:
glyf init # scaffold glyf.yml, visualisations/, dashboards/
dbt build # produce the dbt artifacts glyf reads
glyf doctor # check artifacts, charts, and SQL execution
glyf build # compile, render, and export the site
glyf serve # preview it locallydoctor reports whether the dbt artifacts, chart files, and SQL execution
are ready before your first build, so the first failure is a readable message
rather than a stack trace.
SQL you already know, extended with a visualization grammar. Use ref() to
reference dbt models directly, exactly as a dbt model would:
SELECT month, revenue
FROM {{ ref('fct_orders') }}
VISUALISE month AS x, revenue AS y
DRAW line
LABEL title => 'Monthly Revenue'
LABEL subtitle => 'Revenue trend from dbt model'
CONFIG width => 900glyf resolves each reference to its schema path from target/manifest.json and
validates the query before it renders anything.
Lay charts out into sections. Use Python macros for labels, thresholds, and reusable components, so a dashboard change is a one-line diff in review:
name: executive
title: Executive Dashboard
summary:
- "{{ ui.label_value('Owner', 'Analytics Engineering') }}"
- "{{ ui.label_value('Generated', time.now('%Y-%m-%d %H:%M')) }}"
layout:
columns: 3
sections:
- title: Revenue overview
columns: 3
items:
- metric:
label: Sample revenue
value: "$7.6k"
- chart: revenue
title: Monthly revenue
width: 2One command resolves dbt artifacts, validates chart specs, executes chart SQL against your warehouse, renders charts with Altair, and emits files you can publish:
target/glyf/
├── compiled/ resolved chart SQL
├── charts/ rendered PNG / SVG, and chart metadata
├── data/ chart rows and Vega specs — internal, never published
├── dashboards/ generated dashboard pages
├── assets/ CSS and fonts
├── index.html landing page
├── bundle.json manifest of everything built
└── site/ self-contained static site ← publish this
No BI server to maintain. Drop site/ into S3, GitHub Pages, a docs site, or a
CI artifact. Publish site/ rather than target/glyf/: the rest is working
output, and data/ holds the raw rows.
A published site carries the data behind its charts unless you ask otherwise — see what a published site exposes.
| Command | What it does |
|---|---|
glyf init |
Scaffold glyf config, chart, and dashboard directories |
glyf doctor |
Check dbt artifacts, chart files, and SQL execution |
glyf build |
Full pipeline: compile, render, and export |
glyf serve |
Serve the generated site locally |
glyf list |
List discovered charts and dashboards |
glyf validate |
Validate chart and dashboard specs without rendering |
glyf render |
Render charts only |
glyf dashboard |
Build dashboards only |
glyf export |
Export the publishable site (--clean, --zip) |
Point any command at another project with --project-dir:
glyf build --project-dir examples/sales_dashboardFour runnable projects live in examples/:
simple_dbt, sales_dashboard, product_analytics, and finance_metrics.
uv sync
cd examples/simple_dbt
uv run dbt seed --profiles-dir . --full-refresh --no-partial-parse
uv run dbt run --profiles-dir .
uv run dbt compile --profiles-dir .
uv run glyf build
uv run glyf serveThen open examples/simple_dbt/target/glyf/site/index.html.
| Analytics Engineer | You work in dbt and version-control everything. You should not need LookML or a BI platform UI to publish a declared dashboard artifact. |
| Data Scientist | Write SQL-style chart definitions that run in the pipeline and stay current, instead of one-off notebooks that drift. |
| Data Leader | Open source, runs locally, and produces outputs your team already knows how to deploy and review. |
| Application Engineer | The data team owns the spec; you consume rendered output without negotiating with an embedded analytics vendor. |
| Capability | |
|---|---|
dbt ref() and source() resolution from manifest.json |
shipped |
| GGSQL chart definitions, SQL execution, Altair rendering | shipped |
| Warehouse execution through the dbt profile (DuckDB, Trino, Snowflake, BigQuery) | shipped |
| Dashboard YAML, Python macros, self-contained static site | shipped |
PNG / SVG chart artifacts and --zip export |
shipped |
| Generated typed React components | planned |
| MCP server so agents can reason about the chart graph | planned |
| Visual diff between builds as a CI artifact | planned |
See ROADMAP.md for the longer view.
The full docs site is built from docs-site/
and published at glyf.pages.dev. These guides are also
readable directly in the repository:
| Quickstart | First build, end to end |
| Configuration | glyf.yml reference |
| Visualisation syntax | The GGSQL grammar |
| Dashboard YAML | Layout, sections, macros |
| dbt integration | Artifacts, ref(), adapters |
| CI/CD | Building glyf in a pipeline |
| Troubleshooting | Common failures |
Developing from this repository
uv syncDev dependencies include dbt-core and dbt-duckdb for the bundled examples.
The Makefile runs the same checks locally and in GitHub Actions:
make ci # the full pipeline
make ci PYTHON_VERSION=3.12 # against a specific Pythonmake on its own lists every target. Individual steps: make install,
make test, make coverage, make build, make dashboard-ci. make test
runs pytest with coverage and writes coverage.xml, which CI uploads to
Codecov.
Run the docs site locally with Node.js installed:
cd docs-site
npm install
npm startIssues and pull requests are welcome. Paths in glyf.yml and dashboard YAML use
forward slashes on every platform.