Pewarta Proxy

๐Ÿ“‹ Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

โš™๏ธ Pengaturan Proxy Target

Skip to main content

Build visualizations the way you build pipelines

Glyf is an open source, code-first build step for defining, testing, and shipping charts from your dbt models: as dashboards you host, or drawn live inside your own product.

curl -fsSL https://glyfdata.com/install.sh | sh

macOS and Linux. Other ways to install are in the installation guide.

  • Code-first
  • Rust engine
  • Agent-ready
  • No BI server
dbt modelsYour data models
YAML layoutsDefine charts & pages
Python macrosTransform & extend
Warehouse dataDuckDB ยท Snowflake ยท BigQueryApache Arrow
Glyf buildValidate ยท render ยท export

embedded analytics

Two ways to ship the same charts.

Every chart is SQL in your dbt project, reviewed like code. Publish it as a dashboard, or draw it inside your own product with glyf-js.

The Clanker charts as a glyf dashboard: agent runs, success rate, spend and run time this weekDashboards you hostThe Clanker charts as a glyf dashboard: a static site on any host, with filters, lineage and source. No server, no BI licence.Open this dashboard
Inside your productThe same charts, drawn live inside the Clanker app: its theme, tooltips, the dashboard's filters. Try the model toggles.
Clanker Insights for Glyf DataLive

Spend by model

Agent runs

Spend (USD)

  1. glyf.ymlexport: embed: truePublish each chart live
  2. terminalnpm install @glyf-data/reactAdd the package
  3. Insights.tsx<GlyfChart name="spend_by_model" />Drop in a chart

how it works

Charts, dashboards, and outputs in one build step.

Glyf keeps authoring close to the project: charts as SQL plus a chart block in the ggsql format, dashboard composition in YAML, reusable logic in Python, and outputs from the CLI.

0:00 / 0:42 ยท dbt modelChoose a chapter to jump ahead
01 โ€” Chart Definition

Write charts as SQL

The query you already know, then a few lines saying what to draw. .ggsql files, the ggsql format with Glyf's chart types, and ref() to reach dbt models.

sessions_by_plan.ggsql
SELECT plan, sum(sessions)
FROM {{ ref('fct_usage') }}
GROUP BY 1

VISUALISE plan AS x
DRAW pie
LABEL title => 'Sessions by Plan'
02 โ€” Dashboard Layout

Compose in YAML + Python

Lay out charts into sections. Use Python macros for conditional logic, thresholds, and reusable components.

product.yml
sections:
  - title: Activation
    items:
      - component:
          {{ activation_health(0.82) }}
      - chart: sessions_by_plan
      - chart: active_users
03 โ€” Build Output

Run one command

Glyf resolves dbt artifacts, validates chart specs, renders charts, and emits the files you can publish.

Terminal
$ glyf build

โœ“ Resolved 6 ref() calls
โœ“ Compiled 8 charts
โœ“ Built product.html
โœ“ Wrote chart assets
โœ“ Build complete in 2.1s

features

What makes Glyf different.

Glyf turns visualization into a build step engineers can validate, review, and ship with the rest of the data pipeline. Charts and dashboards stay inside the engineering workflow instead of drifting into disconnected BI tools.

Broken refs and missing charts fail validation before anything ships.
A chart that returns personal data fails the build; a published site carries only the rows you chose.
Integrated with dbt today. SQLMesh and more on the roadmap.
integration

Your dbt project is the source of truth.

Charts reference models with ref(), the way dbt models reference each other, and every reference is checked at build time. No copied SQL and no schema drift.

charts/revenue_weekly.ggsql
-- reference dbt models directly in chart SQL
SELECT
  date_trunc('week', o.created_at) AS week,
  sum(o.revenue_usd) AS revenue,
  p.plan_name
FROM {{ ref('orders') }} o
JOIN {{ ref('plans') }} p
  ON o.plan_id = p.id
GROUP BY 1, 3
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
โœ“ resolved orders โ†’ analytics.orders
โœ“ resolved plans โ†’ analytics.plans
โœ“ query valid โ€” 0 errors
dbt ref() in every chart

Use {{ ref('model') }} in chart SQL exactly as you would in a dbt model. Glyf resolves each reference to its schema path and validates the query before publish.

terminal โ€” git diff
$ git diff main..feat/q3-charts

  charts/revenue_weekly.ggsql- GROUP BY date_trunc('week', created_at)+ GROUP BY date_trunc('month', created_at)
  dashboards/growth.yaml+ - id: new_mrr_cohort+   sql: ./new_mrr_cohort.sql2 files changed, 3 insertions(+), 1 deletion(-)

โœ“ glyf build passed โ€” 14 charts
Ready to merge.
Version controlled, reviewable

Chart definitions, layouts, and macros live in Git alongside your dbt project. Reviewers see exact SQL and YAML diffs, not just screenshots.

ai

Agents that understand your chart graph.

glyf mcp serves a project to an agent over the Model Context Protocol: the charts, what each one draws, which charts a model or column change reaches, and whether an edit still validates. It never runs a build and never fetches rows.

MCP session โ€” Claude Agent โ†” Glyf
agentlist_charts()
glyfโ†’ revenue_weekly, signups_by_plan, churn_cohort, mrr_breakdown (+9)
agentimpact("fct_orders.revenue")
glyfโ†’ read by 4 charts on 2 dashboards: revenue_weekly (revenue AS y), mrr_breakdown, ltv_by_cohort, arpu (SELECT *, may read)
agentvalidate(execute=true)
glyfโ†’ ok: 13 charts, SQL run with LIMIT 0, no rows fetched
resultagent opens the PR naming every downstream chart
Agent-ready MCP server

Six tools built on the CLI's own functions: list charts and dashboards, read a chart's spec, impact for a model or column, validate with a LIMIT 0 dry run, and diff between two builds. An agent can name every downstream chart in the pull request it opens.

MCP session โ€” natural language edit
agent"Change revenue_weekly to group by month and add a plan breakdown"
glyfโ†’ patch revenue_weekly.ggsql
+ GROUP BY date_trunc('month', ...), plan_name
- GROUP BY date_trunc('week', ...)
glyfโ†’ build passed โ€” visual diff attached
resultPR opened with diff + visual artifact
Natural language chart editsComing soon

Describe a chart change in plain language. Glyf will translate it to a SQL diff, validate the build, attach the visual diff, and open a pull request.

exports

Charts that live anywhere.

No BI server to maintain. Glyf builds self-contained artifacts that teams can host in docs, apps, CI pipelines, or static storage.

terminal
$ glyf build --target prod
Building 12 charts...
โœ“ revenue_weekly
โœ“ signups_by_plan
โœ“ churn_cohort
  ... 9 more
Exporting static assets...
โœ“ dist/revenue_weekly.html 42kb
โœ“ dist/signups_by_plan.html 38kb
โœ“ dist/index.html 8kb
โœ“ dist/charts.zip 180kb
No server required.
Drop into S3, Notion, GitHub Pages, or CI artifacts.
Zero-server static output

Each glyf build produces self-contained HTML files with data and rendering logic inlined. Drop them into any static host and they just work.

app/Analytics.tsx
import { GlyfChart, GlyfFilters, GlyfProvider } from '@glyf-data/react'

export function Analytics() {
  return (
    <GlyfProvider bundleUrl="/glyf/bundle.json" theme="dark">
      <GlyfFilters dashboard="insights" />
      <GlyfChart name="spend_by_model" />
    </GlyfProvider>
  )
}

โœ“ npm install @glyf-data/react ยท live charts ยท no BI SDK
React componentsPreview

@glyf-data/react draws the charts from the bundle.json every build writes, live in your own app: tooltips, your theme, the dashboard's filters. On npm. No BI SDK and no server.

customization

Dashboard logic as reviewed code.

Thresholds, color mappings, and conditional labels all live in Python macros and YAML specs. Reusable, testable, and visible in code review.

macros/thresholds.py
from glyf import macro, ChartContext

@macro
def plan_color(ctx: ChartContext, plan: str) -> str:
  return {
    "starter": "#94a3b8",
    "growth": "#6366f1",
    "enterprise": "#0ea5e9",
  }.get(plan, "#e2e8f0")
@macro
def alert_threshold(ctx: ChartContext) -> float:
  return ctx.config["alert_pct"]
{{ plan_color('growth') }} -- โ†’ "#6366f1"
Programmable Python macros

Define reusable chart logic like color mappings, thresholds, and conditional labels as Python functions that are typed, tested, and reviewed.

dashboards/growth.yaml
title: Growth Overview
layout: 2col

charts:
  - id: revenue_weekly
    sql: ./revenue_weekly.sql
    title: Weekly Revenue
    color_macro: plan_color

  - id: churn_cohort
    sql: ./churn_cohort.sql
    visible_if: "user.plan == \'enterprise\'"
โœ“ dashboard spec validated โ€” 3 charts
Dashboard YAML specs

Define layout, chart ordering, visibility conditions, and macro bindings declaratively in YAML. Changing a dashboard becomes a one-line diff.

review

Review the pictures, not just the SQL.

A change to a model or a chart can move a number on a dashboard without touching any file a reviewer would open. Glyf compares every chart in a pull request with the base branch and reports which changed, how much of each picture moved, and why.

terminal โ€” glyf diff
$ git diff main -- models/fct_finance.sql
 from {{ source('raw', 'finance') }}
+where department != 'Partners'
 group by 1, 2
$ glyf diff --baseline ../base
~ bookings_trend: 6.1% of the picture moved (the rows changed)
    points: 12 lower
    sum of bookings 1,079,700 โ†’ 974,000 (-9.8%)
~ expenses_by_department: 50.8% of the picture moved (the rows changed)
    bars: 12 gone (Partners)
    rows 48 โ†’ 36
    gone from department: Partners
    sum of expenses 576,000 โ†’ 527,500 (-8.4%)
~ gross_margin_trend: 7.4% of the picture moved (the rows changed)
    points: 12 lower
    sum of gross_margin 503,700 โ†’ 446,500 (-11.4%)
~ margin_rate_by_department: 35.0% of the picture moved (the rows changed)
    rows 48 โ†’ 36
    gone from department: Partners
~ margin_share: 31.3% of the picture moved (the rows changed)
    rows 4 โ†’ 3
    gone from department: Partners
    sum of gross_margin 503,700 โ†’ 446,500 (-11.4%)
~ margin_vs_expenses: 0.9% of the picture moved (the rows changed)
    rows 48 โ†’ 36
    gone from department: Partners
โœ“ 6 changed, 2 unchanged
โœ“ wrote target/glyf/diff/index.html
A diff that says what moved, and why

First in the chart's terms: bars gone, points higher or lower, and which series. Then the rows: a missing category, a column total, the row count. Then why: the query changed, the rows changed, or only the chart definition did. The same data renders to the same bytes, so an unchanged chart is never reported.

target/glyf/diff/index.html
One chart from the visual diff report, shown three times: before, after, and what moved, where the new bars are drawn over the baseline's in grey and every month that moved is boxed. Above them it says bars: 12 gone (Partners), rows 48 to 36, and the sum of expenses down 8.4 percent.
Before, after, and what moved

Every changed chart is drawn three times: as it was, as it is, and as it is over its old self, the baseline in grey behind the new marks and every category that moved boxed. A series that disappeared stays in the legend with nothing under it. One workflow file puts a summary on the pull request and the full report in its artifacts.

governance

Decide what leaves the warehouse. The build enforces it.

A published dashboard is a file anyone with the link can read. Glyf treats what that file contains as part of the build: which rows it holds, which columns count as personal data, and what happens when a chart reaches for one. Every rule is in glyf.yml, reviewed like the rest.

terminal โ€” glyf build
# glyf.yml
privacy:
  pii_columns: [customer_email]
  on_pii: deny
$ glyf build
โœ“ validated project
Render failed  - visualisations/overdue_invoices.ggsql returns a PII column:    'customer_email'. Drop it from the query, or set    privacy.on_pii: redact to publish it masked.# with on_pii: redact, the build passes and the rows carry
# {"customer_email": "I***", "amount": 16391.88, "days_to_pay": 102}
A chart cannot ship personal data by accident

Columns tagged pii in your dbt schema, or listed in glyf.yml, are known to every build. A query that returns one fails the build naming the chart and the column, or, with on_pii: redact, publishes it masked. A value scan warns about the columns nobody tagged that look like emails, phone or card numbers.

glyf.yml โ†’ target/glyf/site
# one 8-chart dashboard, exported three ways
export.row_data: include   finance.html  106 KB
  every row behind every chart, for interaction
export.row_data: minimal   finance.html  105 KB
  only the columns each chart draws; bookings and
  gross_margin were selected, not plotted: gone
export.row_data: exclude   finance.html   26 KB
  rendered images only. No rows, no specs, no SQL.

# bundle.json records it, every build
"security": { "row_data": "excluded" }
Ship the picture, or the plotted columns, or every row

export.row_data sets what a published site carries. include keeps the rows behind each chart for interactive use. minimal keeps only the columns a chart draws, so a query that selects more than it plots does not publish the rest. exclude ships rendered images and nothing else. bundle.json records which one the build used, so a reviewer can check.

  • Pipeline alerts

    Alert conditions declared in dashboard YAML, evaluated against query results at build time and routed by severity.

    Discuss on GitHub
Missing something?

Describe the chart or workflow you need. Feature requests land on the public roadmap, where anyone can add a ๐Ÿ‘.

Request a feature

who it's for

Built for everyone who touches data.

Analytics Engineer

You work in dbt. Glyf is your next step.

You know SQL. You version-control everything. You should not need LookML or a BI platform UI to publish a declared dashboard artifact.

Data Scientist

Charts in SQL, not one-off notebooks.

Write SQL-style chart definitions that run in the pipeline, stay current, and live beside the models they query.

Data Leader

Reduce platform dependency.

Glyf is open source, runs locally, and produces outputs your team already knows how to deploy and review.

Application Engineer

Import or publish a dashboard artifact.

The data team owns the spec. You fetch bundle.json and show the SVG or PNG it points to, without an embedded analytics vendor.