Library / SDK
microsoft/flint-chart avatar
microsoft/flint-chart

Flint: a chart spec language that compiles to five rendering backends

🪄 Flint is a visualization language that lets AI agents reliably create expressive, good-looking charts from simple, human-editable chart specs.

4,217 stars235 forksTypeScriptMIT

At a glance

What is it?
Microsoft's flint-chart is a TypeScript library and MCP server that turns a compact semantic chart spec into Vega-Lite, ECharts, Chart.js, Plotly, or native Excel output. The interesting part is the intermediate layer; the open question is how much you want a model in the authoring loop.
Who is it for?
Adopt Flint if you are building an agent or a chat surface that has to emit charts and you want one spec shape that lands in whichever backend your host already renders. Do not adopt it if you need a stable, human-authored charting API with a long deprecation record, or if your charts are hand-tuned one-offs where the compiled output will be edited anyway.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

The problem Flint targets is spec authoring by a model, not chart rendering

Most charting libraries assume a person is writing the spec. Vega-Lite is explicit about scales, encodings, and transforms; ECharts wants an option object with axes and series wired by hand. That is fine when a human iterates. It is expensive when a language model is generating the spec, because every verbose parameter is another chance for the model to invent a field name, pick a scale type that does not fit the data, or produce a chart that renders but reads badly. Flint's answer is to shrink the surface the model has to fill in. The README describes the input as a high-level semantic specification plus the data plus an optional theme, with scales, axes, spacing, labels, and layout derived rather than hardcoded. The intended user is therefore not a data journalist hand-tuning a scatter plot. It is a developer wiring chart generation into an agent, a chat client, or a coding environment, who needs the model to produce something acceptable without a review loop on every axis label.

Semantic types and derived layout are the mechanism

The spec has three moving parts. There is data, passed as values. There is a semantic_types map, and the README states Flint captures field meaning through 70 or more semantic types such as Rank, Temperature, Price, or Country. There is a chart_spec, which carries chartType, encodings, and a baseSize. The compile step reads all three and emits a backend-native spec. So the field named weight is not just a number column; it is declared Quantity, and the compiler uses that declaration to decide how the field is presented. Layout is derived from data cardinality, chart design, and canvas constraints, per the feature list. That is the whole trick: the model writes intent, the library writes the parameters. The theme_spec sits alongside chart_spec and is described as defining how meaning is presented, covering layout, labels, legends, axes, mark geometry, and typography. Version 0.5.0 introduced a formal theme specification so a visual system can be defined once and applied across a chart library, and the project site lists presets including New York Times, Economist, Swiss, and McKinsey.

One input shape, five outputs, and what that actually buys

The library exports assembleVegaLite, assembleECharts, assembleChartjs, assemblePlotly, and assembleExcel. The README is direct that every backend accepts the same ChartAssemblyInput and returns the target library's native spec object, and that swapping backends does not change the input shape. That matters for a specific reason: backend choice is often made by the host application, not the chart author. A VS Code extension renders one way, a web dashboard another, a finance team wants a workbook. If the agent has to learn each backend's dialect, the prompt grows and reliability drops. Flint moves that knowledge into the compiler. The Excel path is the outlier worth noting. The README calls the output editable Excel charts and native, and release 0.4.0 added 18 native Excel chart templates. Native and editable are different from exporting an image or an HTML blob, which is the usual way a web chart ends up in a spreadsheet. Whether the compiled Excel artifact survives a round trip through a user's formatting is something the supplied material does not address.

Getting it running: the two install paths

For library use the README gives npm install flint-chart, then an import of assembleVegaLite. The example builds a scatter plot over a dataset with weight, mpg, and origin, declaring weight and mpg as Quantity and origin as Country, with encodings for x, y, and color and a baseSize of 400 by 300. The returned value is described as a ready-to-render Vega-Lite spec. For agent use the command is npx -y flint-chart-mcp, which starts the MCP server locally. There is also a hosted endpoint at https://flint.data-formulator.ai/mcp for clients that support remote HTTP MCP servers, and the README names GitHub Copilot in VS Code and Claude as examples, with the README recommending the local server for large datasets. The prompt example in the README asks the agent to pull public data from Yahoo Finance and compare seven stocks in Economist style, which tells you the intended granularity: one sentence in, a themed chart out. A Python package is listed as to be released, with the current Python port described as a source-only preview in the repository.

The compatibility surface is the cost, and it is not small

Five backends with different capabilities means the shared input shape cannot express everything any one backend can do. The changelog shows the shape of that work: 0.5.1 extended visual themes to the Plotly backend, meaning that before 0.5.1 Plotly did not have the theme support the other backends had. 0.2.1 is described as improving chart-property validation and backend consistency. That is a library still closing gaps between targets, and the release cadence, roughly one minor version every two to three weeks through July and August 2026, is fast. Fast is good for coverage and bad for anyone pinning the API. A second constraint is that a derived layout is a derived layout. If you need a specific annotation placed at a specific coordinate, or a dual-axis chart that breaks the conventions the compiler assumes, you are fighting the abstraction, and the escape hatch is to take the emitted backend spec and edit it, at which point you have given up the round trip. The documentation supplied here does not describe an override mechanism for individual layout decisions, so I cannot say how much control survives.

Where Flint sits next to authoring Vega-Lite directly

The honest comparison is with Vega-Lite itself, which Flint compiles to. Vega-Lite is a declarative grammar with a published schema, a long version history, and a large body of examples. If a person is writing the chart, Vega-Lite is the better tool: the spec is the artifact, it is diffable, and it is portable to any Vega-Lite renderer without Flint in the dependency tree. Flint is aimed at the case where a model writes the spec, and the difference in approach is who supplies the detail. Vega-Lite requires the author to name the scale type, the axis format, the mark, and the layout; Flint infers those from semantic_types and the data. That inference is what makes a short prompt viable, and it is also what makes the output less predictable than a hand-written spec. If your charts are a fixed set that a designer has already specified, compiling through an inference layer adds a dependency and a version to track without adding much. If your charts are generated per request from whatever data the user asked about, the inference layer is doing the work you would otherwise have to prompt for.

Maintenance, licensing, and what to pin

The repository is MIT licensed, which permits commercial use and modification with the licence and copyright notice retained. That is the standard permissive position and it is worth stating plainly rather than treating as a differentiator; the practical implication is that you can vendor the compiler if you need to. There is no legal advice to give beyond that, and the LICENSE file is the authority. On maintenance, the signals in the supplied material are a CI workflow, a changelog kept per release, an arXiv paper referenced in the badge, and a last push in September 2026. The version numbering is pre-1.0, and the 0.2.1 note about backend consistency plus the 0.5.1 note about extending themes to Plotly both indicate that parity across the five targets is still being reached. Two npm packages are involved, flint-chart and flint-chart-mcp, and they version separately, so pinning one does not pin the other. If you deploy the MCP server, the hosted endpoint is a third thing whose version you do not control.

Who this is for, and the one check worth doing first

Flint is for teams putting chart generation behind a model and needing the output to land in a backend they already render. The MCP server plus the shared input shape is the coherent story: the agent learns one spec format, and the host decides whether that becomes Vega-Lite, ECharts, or a spreadsheet. It is not for teams who want a stable declarative grammar to hand-write, and it is not for charts where the layout is the point, because the compiler is making layout decisions on your behalf and the supplied documentation does not describe how to override them individually. The concrete check before adopting: take one real dataset, call assembleVegaLite and assembleECharts on the same ChartAssemblyInput, and compare the two rendered results rather than the two spec objects. If the charts read the same to a viewer, the abstraction is holding. If they do not, you have found the parity gap that the changelog is still working through, and you have found it before it reached a user.

Editorial conclusion

Adopt Flint if you are building an agent or a chat surface that has to emit charts and you want one spec shape that lands in whichever backend your host already renders. Do not adopt it if you need a stable, human-authored charting API with a long deprecation record, or if your charts are hand-tuned one-offs where the compiled output will be edited anyway. Before committing, run assembleVegaLite and assembleECharts on the same ChartAssemblyInput and diff the two outputs; that is the actual promise, and it is the thing worth verifying first.

Official sources

  1. License: MIT
  2. microsoft/flint-chart on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes