Semiotic
React data visualization library for streaming, networks, and AI-assisted development
Install / Use
/learn @nteract/SemioticREADME
A React data visualization library designed for AI-assisted development.
Simple charts in 5 lines. Network graphs, streaming data, and coordinated dashboards when you need them. Structured schemas and an MCP server so AI coding assistants generate correct chart code on the first try.
import { LineChart } from "semiotic"
<LineChart
data={salesData}
xAccessor="month"
yAccessor="revenue"
/>
Why Semiotic
Semiotic is a data visualization library for React that combines broad chart coverage with first-class AI tooling. It handles the chart types that most libraries skip — network graphs, streaming data, statistical distributions, coordinated views — and ships with machine-readable schemas so LLMs can generate correct code without examples.
Built for AI-assisted development
Semiotic ships with everything an AI coding assistant needs to generate correct visualizations without trial and error:
semiotic/ai— a single import with all 38 chart components, optimized for LLM code generationai/schema.json— machine-readable prop schemas for every componentnpx semiotic-mcp— an MCP server for tool-based chart rendering in any MCP clientnpx semiotic-ai --doctor— validate component + props JSON from the command line with typo suggestions and anti-pattern detectiondiagnoseConfig(component, props)— programmatic anti-pattern detector with 12 checks and actionable fixesCLAUDE.md— instruction files auto-synced for Claude, Cursor, Copilot, Windsurf, and Clinellms.txt— machine-readable documentation following the emerging standard
Every chart includes a built-in error boundary, dev-mode validation
warnings with typo suggestions, and accessibility features (canvas
aria-label, keyboard-navigable legends, aria-live tooltips, SVG
<title>/<desc>) so AI-generated code fails gracefully with
actionable diagnostics instead of a blank screen.
Beyond standard charts
Network visualization. Force-directed graphs, Sankey diagrams, chord diagrams, tree layouts, treemaps, circle packing, and orbit diagrams — all as React components with the same prop API as LineChart.
Streaming data. Realtime charts render on canvas at 60fps with a ref-based push API. Built-in decay, pulse, and staleness encoding for monitoring dashboards.
Coordinated views. LinkedCharts provides hover cross-highlighting,
brush cross-filtering, coordinate-based linked crosshairs, and selection
synchronization across any combination of chart types — zero wiring.
Geographic visualization. Choropleth maps, proportional symbol maps, flow maps with animated particles, and distance cartograms — all canvas-rendered with d3-geo projections, zoom/pan, tile basemaps, and drag-rotate globe spinning.
Statistical summaries. Box plots, violin plots, swarm plots, histograms, LOESS smoothing, forecast with confidence envelopes, and anomaly detection. Marginal distribution graphics on scatterplot axes with a single prop.
Start simple, go deep
| Layer | For | Example |
|---|---|---|
| Charts | Common visualizations with sensible defaults | <LineChart data={d} xAccessor="x" yAccessor="y" /> |
| Frames | Full control over rendering, interaction, and layout | <StreamXYFrame chartType="line" lineStyle={...} /> |
Every Chart component accepts a frameProps prop to access the underlying
Frame API without leaving the simpler interface.
Serialization and interop
Charts serialize to JSON and back: toConfig, fromConfig, toURL,
copyConfig, configToJSX. Have Vega-Lite specs? fromVegaLite(spec)
translates them to Semiotic configs — works with configToJSX() for
full round-trip from notebooks and AI-generated specs.
When to use something else
Need a standard bar or line chart for a dashboard you'll never need to customize beyond colors and labels? Recharts has a larger ecosystem and more community examples. Need GPU-accelerated rendering for millions of data points? Apache ECharts handles that scale.
Semiotic is for projects that outgrow those libraries — when you need network graphs alongside time series, streaming data alongside static snapshots, or coordinated views across chart types.
Install
npm install semiotic
Requires React 18.1+ or React 19.
Quick Examples
Coordinated Dashboard
Hover one chart, highlight the same data in another — zero wiring:
import { LinkedCharts, Scatterplot, BarChart } from "semiotic"
<LinkedCharts>
<Scatterplot
data={data} xAccessor="age" yAccessor="income" colorBy="region"
linkedHover={{ name: "hl", fields: ["region"] }}
selection={{ name: "hl" }}
/>
<BarChart
data={summary} categoryAccessor="region" valueAccessor="total"
selection={{ name: "hl" }}
/>
</LinkedCharts>
Streaming Metrics with Decay
Live data fades old points, flashes new ones, flags stale feeds:
import { RealtimeLineChart } from "semiotic"
const chartRef = useRef()
chartRef.current.push({ time: Date.now(), value: cpuLoad })
<RealtimeLineChart
ref={chartRef}
timeAccessor="time"
valueAccessor="value"
decay={{ type: "exponential", halfLife: 100 }}
staleness={{ threshold: 5000, showBadge: true }}
/>
Network Graphs
Force-directed graphs and Sankey diagrams — same API as LineChart:
import { ForceDirectedGraph, SankeyDiagram } from "semiotic"
<ForceDirectedGraph
nodes={people} edges={friendships}
colorBy="team" nodeSize={8} showLabels
/>
<SankeyDiagram
edges={budgetFlows}
sourceAccessor="from" targetAccessor="to" valueAccessor="amount"
/>
Geographic Visualization
Choropleth maps, flow maps, and distance cartograms with canvas rendering, zoom/pan, tile basemaps, and animated particles:
import { ChoroplethMap, FlowMap, DistanceCartogram } from "semiotic/geo"
<ChoroplethMap
areas={geoJsonFeatures} valueAccessor="gdp"
colorScheme="viridis" projection="equalEarth" zoomable tooltip
/>
<FlowMap
nodes={airports} flows={routes} valueAccessor="passengers"
showParticles particleStyle={{ color: "source", speedMultiplier: 1.5 }}
/>
<DistanceCartogram
points={cities} center="rome" costAccessor="travelDays"
showRings costLabel="days" lines={routes}
/>
Streaming System Monitor
Live service topology with threshold alerting and click-to-inspect:
import { StreamNetworkFrame, ChartContainer, DetailsPanel, LinkedCharts } from "semiotic"
const chartRef = useRef()
chartRef.current.push({ source: "API", target: "Orders", value: 15 })
<LinkedCharts>
<ChartContainer title="System Monitor" status="live"
detailsPanel={
<DetailsPanel position="right" trigger="click">
{(datum) => <div>{datum.id}: {datum.value} req/s</div>}
</DetailsPanel>
}>
<StreamNetworkFrame ref={chartRef} chartType="sankey"
showParticles particleStyle={{ proportionalSpeed: true }}
thresholds={{ metric: n => n.value, warning: 100, critical: 250 }}
/>
</ChartContainer>
</LinkedCharts>
Standard Charts
Line, bar, scatter, area — all the basics, with sensible defaults:
import { LineChart, BarChart } from "semiotic"
<LineChart
data={salesData}
xAccessor="month" yAccessor="revenue"
curve="monotoneX" showPoints
/>
<BarChart
data={categoryData}
categoryAccessor="department" valueAccessor="sales"
orientation="horizontal" colorBy="region"
/>
All Chart Components
| Category | Components |
|---|---|
| XY | LineChart AreaChart StackedAreaChart Scatterplot ConnectedScatterplot BubbleChart Heatmap QuadrantChart MultiAxisLineChart MinimapChart |
| Categorical | BarChart StackedBarChart GroupedBarChart LikertChart SwimlaneChart FunnelChart SwarmPlot BoxPlot Histogram ViolinPlot RidgelinePlot DotPlot PieChart DonutChart |
| Network | ForceDirectedGraph ChordDiagram SankeyDiagram TreeDiagram Treemap CirclePack OrbitDiagram |
| Geo | ChoroplethMap ProportionalSymbolMap FlowMap DistanceCartogram |
| Realtime | RealtimeLineChart RealtimeHistogram RealtimeSwarmChart RealtimeWaterfallChart RealtimeHeatmap |
| Coordination | LinkedCharts ScatterplotMatrix |
| Layout | ChartGrid ContextLayout CategoryColorProvider |
| Frames | StreamXYFrame StreamOrdinalFrame StreamNetworkFrame StreamGeoFrame |
Vega-Lite Translation
Paste a Vega-Lite spec, get a Semiotic chart:
import { fromVegaLite } from "semiotic/data"
import { configToJSX, fromConfig } from "semiotic"
const config = fromVegaLite({
mark: "bar",
data: { values: [{ a: "A", b: 28 }, { a: "B", b: 55 }] },
encoding: {
x: { field: "a", type: "nominal" },
y: { field: "b", type: "quantitative" },
},
})
// Render directly
const { componentName, props } = fromConfig(config)
// → componentName: "BarChart", props: { data, categoryAccessor: "a", valueAccessor: "b" }
// Or generate JSX code
configToJSX(config)
// → <BarChart data={[...]} categoryAccessor="a" valueAccessor="b" />
Supports bar, line, area, point, rect, arc, tick marks with encoding translation for color, size, aggregation, and binning.
Smaller Bundles
Import only what you need:
import { LineChart } from "semiotic/xy" // ~123 KB gzip

