# flint-chart

Flint is a charting language meant for LLM agents to emit. Instead of having an agent hand-write a full Vega-Lite, ECharts, or Chart.js config — with all the scales, axes, spacing, and legend details that go with it — the agent writes a compact spec that says what the data is, what each field means, which chart type to use, and how fields map to encodings. A compiler fills in the rest and produces a backend-native spec ready to render. It comes from Microsoft Research together with the IDEAS Lab at Renmin University of China.

The pitch is a split the project makes explicit: simple chart specs are easy for a model to produce reliably but look bad because they lean on system defaults; detailed specs look good but are verbose enough that agents make mistakes. Flint's answer is to keep the input small and push the layout decisions into a deterministic compiler. That puts it in the same shape as other agent-facing designs where the model emits a small intermediate representation and a non-LLM layer does the exacting part — see [[structured-output-benchmark]] for the general reliability problem of getting models to emit valid structured output.

## How it works

The input is a `ChartAssemblyInput` object with three parts: the `data` (inline rows or a URL to a JSON/CSV/TSV file), `semantic_types` mapping each field to one of 70+ meanings (`Quantity`, `Country`, `Rank`, `Temperature`, `Price`, and so on), and a `chart_spec` giving the chart type, the field-to-encoding mapping, and a base size. The compiler reads the semantic types and data cardinality to derive sizing, spacing, label placement, mark choices, and legends automatically, so the agent never sets those directly.

The same input compiles to three backends through three functions — `assembleVegaLite`, `assembleECharts`, `assembleChartjs` — each returning that library's native spec object. Swapping backend means swapping the call, not rewriting the input. Around 30+ chart types are supported across the three renderers.

Two packages ship on npm: `flint-chart`, the TypeScript compiler library, and `flint-chart-mcp`, an MCP server that hands an agent Flint tools plus chart-selection guidance so it can pick a template, validate it, and open an interactive chart view (or return static PNG/SVG, or the raw backend spec) inside the same chat. For agent setups without MCP there's a standalone agent skill in the repo. A Python port exists in-tree as a source-only preview; the Python package hasn't been released yet.

## Usage

As a library:

```ts
import { assembleVegaLite } from 'flint-chart';

const spec = assembleVegaLite({
  data: { values: myData },
  semantic_types: { weight: 'Quantity', mpg: 'Quantity', origin: 'Country' },
  chart_spec: {
    chartType: 'Scatter Plot',
    encodings: { x: { field: 'weight' }, y: { field: 'mpg' }, color: { field: 'origin' } },
    baseSize: { width: 400, height: 300 },
  },
});
// → a ready-to-render Vega-Lite spec
```

Same input, different backend:

```ts
import { assembleECharts, assembleChartjs } from 'flint-chart';

const echartsOption = assembleECharts(input);
const chartjsConfig = assembleChartjs(input);
```

As an MCP server, point an MCP client at `npx -y flint-chart-mcp`. The agent can then embed rows as `data.values` or read a local JSON/CSV/TSV file via `data.url`.

## Limitations

Node 18+ is required for the JS library. The Python package is not released — only a source preview lives in the repo. The spec is JSON, which several commenters on the launch thread flagged as machine-friendly but not the most natural thing for a model to write or a human to edit; whether that matters in practice is unsettled. There's a fair critique that current models are already competent at one-shotting matplotlib, R, or Vega, so the win depends on Flint's compact spec being both more token-efficient and more reliable than generating renderer code directly — and the project ships no benchmark on either axis yet. The spec doesn't currently support layering or composition of multiple charts. A research paper is described as "coming soon." Accessibility of the generated charts isn't addressed in the docs.

Because it's an early research release with an evolving spec, a pending paper, and an unreleased Python port, it's on [[toolbox/watchlist]] — worth re-checking once the API settles and benchmarks appear.

[github.com/microsoft/flint-chart](https://github.com/microsoft/flint-chart) — 1,902 stars, MIT license.
