CLI tool
bruin-data/dac avatar
bruin-data/dac

DAC: dashboards as YAML and TSX files, served by a Go binary

DaC is a dashboard-as-code tool. Build interactive dashboards using YAML and JSX. Built-in semantic layer. Get your agents to build standardized, reviewable dashboards.

736 stars33 forksGoAGPL-3.0

At a glance

What is it?
DAC turns dashboards into reviewable files, with a semantic layer that generates the SQL and a bundled skill that teaches Claude and Codex to write them. It is a young project with a narrow integration surface, and the AGPL-3.0 licence is the first thing to check.
Who is it for?
Adopt DAC if your dashboards already live next to Bruin connections and you want them reviewed in pull requests rather than edited in a BI UI. Skip it if you need a stable schema or cannot accept AGPL-3.0.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem DAC targets: dashboards that live in a UI and cannot be reviewed

Most dashboard tools store the definition inside the product. A chart is a row in a database you do not control, and the only way to review a change is to look at the rendered result. DAC takes the opposite position: a dashboard is a file, and the file is the artefact under review.

The tool is aimed at teams that already treat SQL and transformation code as versioned text. The README states it plainly: DAC is a Dashboard-as-Code tool for defining, validating, and serving dashboards from YAML and TSX. There is also a second audience named in the repository description, and it is the more interesting one. DAC is built for AI agents to build dashboards in a reliable and reviewable way. The bet is that a language model writing a constrained YAML or TSX file, validated by a CLI, produces something a human can diff, whereas a model clicking through a BI interface produces something nobody can audit.

That framing explains most of the design decisions below, including the semantic layer and the bundled skills directory.

Two authoring formats, one semantic layer, and where the SQL is actually generated

A dashboard can be written in YAML or in TSX, and the README shows the same metric widget in both. The YAML form is a tree: a name, a connection, then rows containing widgets, each widget carrying a name, a type, a sql string, a value block describing field and format, and a col width. The TSX form is JSX with components such as Dashboard, Row and Metric, which is what allows the dynamic behaviour the README lists: charts, tabs, loops and conditionals resolved at load time.

The semantic layer is the part that changes the work. Metrics and dimensions are defined once under semantic/, and widgets reference them instead of embedding SQL. DAC then generates the SQL. Two of the four bundled examples exist to demonstrate this: examples/semantic-yaml reads semantic models from semantic/ and compiles widgets in the backend, while examples/semantic-tsx uses external semantic models with the same backend compilation. The repository layout confirms the split, with pkg/ holding the dashboard loading, the semantic engine, the server and the query backends, and frontend/ holding a React frontend that is embedded into the binary.

Query execution is not handled in-process. The README says DAC uses your existing Bruin connections and currently shells out to bruin query. That word, currently, is doing real work. It tells you the architecture has a seam where a native execution path could replace a subprocess call, and that today you inherit whatever Bruin supports. The README lists Postgres, MySQL, Snowflake, BigQuery, Redshift and Databricks, with more available via Bruin.

Install, validate, serve: the three commands that matter

Installation is a shell script from the project's own domain. The README gives curl -LsSf https://getbruin.com/install/dac | sh for the latest stable release, and the same command with -s -- --channel edge for builds from main. The script installs the Bruin CLI first when bruin is not already on your PATH, which is consistent with the shell-out design described above.

The quickstart is four commands. dac init my-dashboards creates a starter project. dac validate --dir . checks it. dac validate --dir . --with-database goes further and checks against a live database, which is the difference between a syntax check and a real one. dac serve --dir . --open starts the server and opens the browser. The starter project is not empty: it ships a SQL-backed YAML dashboard, a semantic YAML dashboard, and a semantic model under semantic/.

For an existing repository, dac init is not the entry point. The README says to run dac skills install --dir . instead, which installs the authoring skill without scaffolding a new project. If you cloned the repository and have dac on your PATH, dac serve --dir examples/basic-yaml runs one of the bundled examples directly. Development uses make targets (make deps, make test, make build, make dev) rather than ad-hoc go build or npm run build calls, because the frontend embedding and build flags depend on the Makefile doing the work.

The agent skill is the most opinionated part of the project

dac init does more than create directories. It installs DAC's bundled dashboard authoring skill for Claude and Codex, at .claude/skills/create-dashboard/SKILL.md and .codex/skills/create-dashboard respectively. The README treats these paths as verifiable, listing ls commands for both.

This is a concrete answer to a real problem. An agent asked to build a dashboard from scratch will invent a structure, and the structure will drift between runs. A skill file pins the conventions: which directory holds semantic models, how a widget declares its value field, what a valid connection reference looks like. Combined with dac validate, it gives the agent a feedback loop that does not require a human to open a browser.

I would treat the skill files as the least stable surface in the project. They encode conventions that the CLI also encodes, and the two can fall out of step across releases. If you upgrade DAC, re-read the installed skill rather than assuming the old copy still matches the validator's expectations. That is a guess about maintenance risk, not something the README states.

Telemetry is on by default, and the README is specific about what leaves the machine

DAC sends anonymous usage events. According to the README, each event carries the command name, run duration, OS and architecture, DAC version, and an anonymous install ID stored at ~/.dac/telemetry.json. The README then enumerates what is not collected: SQL queries, query results and row counts; dashboard and widget contents, names and file paths; connection names, hosts, credentials, project IDs and dataset names; environment variables and shell history.

Two details stand out. First, builds without a telemetry write key are silent, and the README says this is the default for make build, so anyone compiling from source sends nothing without configuring anything. Second, opt-out uses either TELEMETRY_OPTOUT=1 or the industry-standard DO_NOT_TRACK=1.

The claim that query text never leaves the machine is the one to check against your own threat model, because DAC shells out to bruin query and the telemetry boundary is described in prose rather than in a schema. If your queries contain identifiers you cannot disclose, set DO_NOT_TRACK=1 before the first run rather than after.

Where DAC is the wrong tool

The Bruin dependency is not incidental. Query execution goes through the Bruin CLI, connections come from Bruin, and the installer will fetch Bruin if it is missing. If your organisation does not run Bruin and does not want a second CLI in the deployment path, DAC is not a drop-in. You are adopting two tools, and the second one owns the part that touches your warehouse.

Versioning is the second constraint. The release list shows v0.16.0 and v0.15.1 within a day of each other, alongside an edge build tagged v0.0.0-edge.76.909cce9. The project is pre-1.0 and shipping frequently, which is good for the semantic layer and bad for anyone who needs a frozen schema for dashboard files. There is no stated compatibility guarantee in the material available, so a YAML file that validates today may need edits after an upgrade.

The third constraint is licensing, and it is the one that disqualifies DAC for some teams outright. The licence is AGPL-3.0-only. Running a modified DAC as a network service is the scenario that licence is written for, and whether your deployment triggers its obligations is a question for your own counsel. What can be said without legal advice is that AGPL-3.0 is a materially different commitment from the MIT and Apache-2.0 licences most dashboard tooling ships under, and it should be the first item on the checklist, not the last.

Compared with Grafana: provisioned dashboards versus a compiled semantic layer

Grafana is the obvious reference point for anyone evaluating DAC, because it solves the same top-level problem. Grafana dashboards can be defined as JSON and provisioned from files, so they can live in Git and be reviewed. The similarity ends at the file format.

In Grafana, a panel is bound to a query against a data source, and the query is written per panel. Reuse happens through dashboard variables and library panels, both of which are presentation-level mechanisms. DAC pushes reuse down into a semantic layer: a metric is defined once under semantic/, and widgets reference it, with DAC generating the SQL. Change the metric definition and every widget that references it changes, without editing the widgets. That is a different kind of guarantee, and it is the reason the semantic examples exist in the repository.

The trade-off runs the other way too. Grafana's provisioning format is JSON, verbose but widely documented, and Grafana has a large ecosystem of data source plugins. DAC's query surface is whatever Bruin exposes, and its authoring surface is YAML plus TSX. TSX buys loops and conditionals that Grafana provisioning cannot express, but it also means a dashboard can contain arbitrary logic, which is exactly the property that made UI-based dashboards hard to review in the first place. YAML dashboards are the safer choice for teams whose main goal is auditability.

Maintenance cost and who should adopt it

The maintenance surface has four parts. The DAC binary itself, upgraded on whatever cadence you choose. The Bruin CLI underneath it, which owns connections and query execution. The semantic models under semantic/, which are your code and your responsibility. And the agent skill files, which are regenerated by dac skills install and should be re-read after upgrades.

Adopt DAC if you already use Bruin, if your dashboards are consumed by engineers who read pull requests, and if you want one metric definition to drive many widgets. The semantic examples under examples/semantic-yaml and examples/semantic-tsx are the fastest way to judge whether the abstraction fits your data model, and they run with a single dac serve --dir command.

Do not adopt it if a subprocess call to another CLI is unacceptable in your serving path, if you need a stable file format before 1.0, or if AGPL-3.0 does not fit your distribution model. Teams that only need provisioned dashboards and already run Grafana will find the semantic layer is the only thing DAC adds that Grafana does not, and they should decide whether that alone justifies a second toolchain.

What to verify first is narrow and testable. Run dac validate --dir . --with-database against a real warehouse connection, not the starter project's fixtures, because that is the only command in the README that exercises the path from a widget through the semantic layer to generated SQL. Then set DO_NOT_TRACK=1 and confirm nothing is written to ~/.dac/telemetry.json on a subsequent run.

Editorial conclusion

Adopt DAC if your dashboards already live next to Bruin connections and you want them reviewed in pull requests rather than edited in a BI UI. Skip it if you need a stable schema or cannot accept AGPL-3.0. Before committing, run dac validate --dir . --with-database against your real warehouse and read the telemetry section of the README to decide whether to export DO_NOT_TRACK=1.

Official sources

  1. bruin-data/dac on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes