Dashboards your
coding agent can ship.

Point Claude Code, Cursor, or any LLM workflow at a CSV or BigQuery dataset. Your agent writes a dashboard.yaml; dashctl compiles it to one self-contained HTML file. No clicks, no SaaS, no runtime to host.

dashctl demo dashboard
{}

Declarative, not click-driven

LLMs write structured config a hundred times better than they drive a BI tool's UI. dashctl is config-only by design — no canvas, no drag-drop, no hidden state to reverse-engineer.

ok

Schema-validated & deterministic

Mechanical errors with line numbers and field names. dashctl validate returns zero or non-zero, so your agent iterates without guessing.

1

One HTML file out

No server, no runtime, no telemetry. Your agent hands you a single file. You open it, email it, drop it on S3 — and it still queries live BigQuery if you want it to.

The format your agent writes. The output you get.

Left: what an LLM emits when you ask for a sales dashboard. Right: what you (or the agent) run. One file out — no servers, no build step at view time.

# dashboard.yaml — what the agent writes
title: Sales
theme: light

sources:
  orders:
    type: csv
    url: ./orders.csv

panels:
  - row:
      - type: kpi
        title: Total revenue
        source: orders
        query: SELECT SUM(amount) AS [value] FROM orders
        format: currency
      - type: line
        title: Revenue over time
        source: orders
        query: SELECT date, SUM(amount) AS revenue FROM orders GROUP BY date
        x: date
        y: revenue
# in your agent / terminal
> "Build a sales dashboard from
>  ./orders.csv with revenue, top
>  customers, region breakdown."

# the agent emits dashboard.yaml, then:
$ dashctl validate dashboard.yaml
[validate] ok — 4 panels, 1 source

$ dashctl build dashboard.yaml -o dash.html
[build] wrote dash.html (842 KB)

# one file. open it, email it,
# drop it on S3.

Why agents like it.

dashctl was designed assuming the author is an LLM, not a human clicking through a tool.

</>

No template language

Pure YAML + SQL. No Jinja, no JSX, no Vega-Lite spec to memorize. Smaller surface area means smaller hallucination surface.

==

Idempotent builds

Same YAML + same data → byte-identical HTML. Diffs in PRs are readable, regressions are obvious, agents can self-verify.

db

Real data backends

BigQuery via a local proxy (ADC, no browser OAuth dance) and DuckDB-WASM in the browser. Agents wire to live sources, not just CSV snapshots.

Wire it to your agent in three commands.

  1. npm install -g dashctl
    Node 20+. Global so your agent can shell out from anywhere. DuckDB-WASM is an optional dep — only pulled if you use it.
  2. dashctl init my-dashboard
    Scaffolds a working dashboard.yaml with a yaml-language-server schema reference — your agent gets autocomplete and structural validation in-editor.
  3. dashctl build dashboard.yaml -o dash.html
    That's the inner loop. Pair with dashctl validate for a deterministic pre-flight: zero exit code or a precise YAML location to fix.