{"id":13426402,"url":"https://github.com/nteract/semiotic","last_synced_at":"2026-06-08T05:01:13.331Z","repository":{"id":23782342,"uuid":"85225460","full_name":"nteract/semiotic","owner":"nteract","description":"React data visualization library for streaming, networks, and AI-assisted development","archived":false,"fork":false,"pushed_at":"2026-06-01T22:54:33.000Z","size":45486,"stargazers_count":2670,"open_issues_count":0,"forks_count":137,"subscribers_count":41,"default_branch":"main","last_synced_at":"2026-06-02T00:18:26.021Z","etag":null,"topics":["ai","d3","data-visualization","nteract","react","streaming","visualization"],"latest_commit_sha":null,"homepage":"https://semiotic.nteract.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nteract.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-03-16T17:46:24.000Z","updated_at":"2026-06-01T22:54:39.000Z","dependencies_parsed_at":"2023-02-16T16:30:44.456Z","dependency_job_id":"8e598f01-4f20-40d7-9f4d-d057ffd82560","html_url":"https://github.com/nteract/semiotic","commit_stats":{"total_commits":2329,"total_committers":39,"mean_commits":"59.717948717948715","dds":"0.28595963933018465","last_synced_commit":"1bf2138b05955b75dedcc7ebb6f98d6ee96b257a"},"previous_names":[],"tags_count":209,"template":false,"template_full_name":null,"purl":"pkg:github/nteract/semiotic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fsemiotic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fsemiotic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fsemiotic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fsemiotic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nteract","download_url":"https://codeload.github.com/nteract/semiotic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nteract%2Fsemiotic/sbom","scorecard":{"id":697618,"data":{"date":"2025-08-11","repo":{"name":"github.com/nteract/semiotic","commit":"b64e5db4a6e601e5b98c882474fe5738600ee3c6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/13 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/node.js.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Security-Policy","score":9,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Warn: One or no descriptive hints of disclosure, vulnerability, and/or timelines in security policy","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/nteract/semiotic/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/nteract/semiotic/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/nteract/semiotic/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/nteract/semiotic/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.js.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/nteract/semiotic/node.js.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.js.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/nteract/semiotic/node.js.yml/main?enable=pin","Warn: npmCommand not pinned by hash: scripts/create-release-branch.sh:9","Warn: npmCommand not pinned by hash: scripts/publish-release.sh:28","Warn: npmCommand not pinned by hash: .github/workflows/node.js.yml:28","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"21 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-xq7p-g2vc-g82p","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T04:11:54.446Z","repository_id":23782342,"created_at":"2025-08-22T04:11:54.446Z","updated_at":"2025-08-22T04:11:54.446Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34048682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","d3","data-visualization","nteract","react","streaming","visualization"],"created_at":"2024-07-31T00:01:33.632Z","updated_at":"2026-06-08T05:01:13.323Z","avatar_url":"https://github.com/nteract.png","language":"TypeScript","funding_links":[],"categories":["Data Visualization","JavaScript","UI Components","Uncategorized","Charts","data-visualization","📊 Data \u0026 Analytics","TypeScript"],"sub_categories":["Data Visualization","Uncategorized"],"readme":"[![Semiotic](semiotic_logo_horizontal.png \"semiotic\")](https://semiotic.nteract.io)\n\n[![CI](https://github.com/nteract/semiotic/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/nteract/semiotic/actions/workflows/node.js.yml)\n[![npm version](https://img.shields.io/npm/v/semiotic.svg)](https://www.npmjs.com/package/semiotic)\n[![TypeScript](https://img.shields.io/badge/TypeScript-built--in-blue.svg)](https://www.typescriptlang.org/)\n[![semiotic MCP server](https://glama.ai/mcp/servers/nteract/semiotic/badges/card.svg)](https://glama.ai/mcp/servers/nteract/semiotic)\n[![MseeP.ai Security Assessment Badge](https://mseep.net/pr/nteract-semiotic-badge.png)](https://mseep.ai/app/nteract-semiotic)\n\nA React data visualization library designed for AI-assisted development.\n\nSimple charts in 5 lines. Network graphs, streaming data, and coordinated\ndashboards when you need them. Structured schemas and an MCP server so\nAI coding assistants generate correct chart code on the first try.\n\n```jsx\nimport { LineChart } from \"semiotic/xy\"\n\n\u003cLineChart\n  data={salesData}\n  xAccessor=\"month\"\n  yAccessor=\"revenue\"\n/\u003e\n```\n\n## Why Semiotic\n\nSemiotic is a data visualization library for React that combines broad chart\ncoverage with first-class AI tooling. It handles the chart types that most\nlibraries skip — network graphs, streaming data, statistical distributions,\ncoordinated views — and ships with machine-readable schemas so LLMs can\ngenerate correct code without examples.\n\n### Built for AI-assisted development\n\nSemiotic ships with everything an AI coding assistant needs to generate\ncorrect visualizations without trial and error:\n\n- **`semiotic/ai`** — a single import with the 47-chart capability catalog (XY, ordinal, network, realtime, geo, value), optimized for LLM code generation. Prefer family subpaths such as `semiotic/xy`, `semiotic/geo`, and `semiotic/value` when bundle size matters.\n- **`ai/schema.json`** — machine-readable prop schemas for every component\n- **`npx semiotic-mcp`** — an MCP server for tool-based chart rendering in any MCP client\n- **`npx semiotic-ai --doctor`** — validate component + props JSON from the command line with typo suggestions and anti-pattern detection\n- **`diagnoseConfig(component, props)`** — programmatic anti-pattern detector with 12 checks and actionable fixes\n- **`CLAUDE.md`** — instruction files auto-synced for Claude, Cursor, Copilot, Windsurf, and Cline\n- **`llms.txt`** — machine-readable documentation following the emerging standard\n\nEvery chart includes a built-in error boundary, dev-mode validation\nwarnings with typo suggestions, and accessibility features (canvas\n`aria-label`, keyboard-navigable legends, `aria-live` tooltips, SVG\n`\u003ctitle\u003e`/`\u003cdesc\u003e`) so AI-generated code fails gracefully with\nactionable diagnostics instead of a blank screen.\n\n### Beyond standard charts\n\n**Network visualization.** Force-directed graphs, Sankey diagrams, chord\ndiagrams, tree layouts, treemaps, circle packing, and orbit diagrams — all\nas React components with the same prop API as LineChart.\n\n**Streaming data.** Realtime charts render on canvas at 60fps with a\nref-based push API. Built-in decay, pulse, and staleness encoding for\nmonitoring dashboards.\n\n**Coordinated views.** `LinkedCharts` provides hover cross-highlighting,\nbrush cross-filtering, coordinate-based linked crosshairs, and selection\nsynchronization across any combination of chart types — zero wiring.\n\n**Geographic visualization.** Choropleth maps, proportional symbol maps, flow\nmaps with animated particles, and distance cartograms — all canvas-rendered\nwith d3-geo projections, zoom/pan, tile basemaps, and drag-rotate globe spinning.\n\n**Statistical summaries.** Box plots, violin plots, swarm plots, histograms,\nLOESS smoothing, forecast with confidence envelopes, and anomaly detection.\nMarginal distribution graphics on scatterplot axes with a single prop.\n\n**First-class annotations.** Annotations are data-bound objects, not post-hoc\nartwork. Labels, callouts, thresholds, enclosures, statistical overlays, and\nReact widgets move with the chart and render through browser, SSR, and export\npaths. Opt into placement, hierarchy, density, progressive disclosure,\naudience-aware amount, provenance, and editorial lifecycle when the chart\nneeds to communicate more than its encoding alone.\n\n### Start simple, go deep\n\n| Layer | For | Example |\n|---|---|---|\n| **Charts** | Common visualizations with sensible defaults | `\u003cLineChart data={d} xAccessor=\"x\" yAccessor=\"y\" /\u003e` |\n| **Frames** | Full control over rendering, interaction, and layout | `\u003cStreamXYFrame chartType=\"line\" lineStyle={...} /\u003e` |\n\nEvery Chart component accepts a `frameProps` prop to access the underlying\nFrame API without leaving the simpler interface.\n\n### Serialization and interop\n\nCharts serialize to JSON and back: `toConfig`, `fromConfig`, `toURL`,\n`copyConfig`, `configToJSX`. Have Vega-Lite specs? `fromVegaLite(spec)`\ntranslates them to Semiotic configs — works with `configToJSX()` for\nfull round-trip from notebooks and AI-generated specs.\n\n### When to use something else\n\nNeed a standard bar or line chart for a dashboard you'll never need to\ncustomize beyond colors and labels? [Recharts](https://recharts.org) has a\nlarger ecosystem and more community examples. Need GPU-accelerated rendering\nfor millions of data points? [Apache ECharts](https://echarts.apache.org)\nhandles that scale.\n\nSemiotic is for projects that outgrow those libraries — when you need\nnetwork graphs alongside time series, streaming data alongside static\nsnapshots, or coordinated views across chart types.\n\n## Install\n\n```bash\nnpm install semiotic\n```\n\nRequires React 18.1+ or React 19.\n\n## Quick Examples\n\n### Coordinated Dashboard\n\nHover one chart, highlight the same data in another — zero wiring:\n\n```jsx\nimport { LinkedCharts, Scatterplot, BarChart } from \"semiotic\"\n\n\u003cLinkedCharts\u003e\n  \u003cScatterplot\n    data={data} xAccessor=\"age\" yAccessor=\"income\" colorBy=\"region\"\n    linkedHover={{ name: \"hl\", fields: [\"region\"] }}\n    selection={{ name: \"hl\" }}\n  /\u003e\n  \u003cBarChart\n    data={summary} categoryAccessor=\"region\" valueAccessor=\"total\"\n    selection={{ name: \"hl\" }}\n  /\u003e\n\u003c/LinkedCharts\u003e\n```\n\n### Streaming Metrics with Decay\n\nLive data fades old points, flashes new ones, flags stale feeds:\n\n```jsx\nimport { RealtimeLineChart } from \"semiotic\"\n\nconst chartRef = useRef()\nchartRef.current.push({ time: Date.now(), value: cpuLoad })\n\n\u003cRealtimeLineChart\n  ref={chartRef}\n  timeAccessor=\"time\"\n  valueAccessor=\"value\"\n  decay={{ type: \"exponential\", halfLife: 100 }}\n  staleness={{ threshold: 5000, showBadge: true }}\n/\u003e\n```\n\n### Network Graphs\n\nForce-directed graphs and Sankey diagrams — same API as LineChart:\n\n```jsx\nimport { ForceDirectedGraph, SankeyDiagram } from \"semiotic\"\n\n\u003cForceDirectedGraph\n  nodes={people} edges={friendships}\n  colorBy=\"team\" nodeSize={8} showLabels\n/\u003e\n\n\u003cSankeyDiagram\n  edges={budgetFlows}\n  sourceAccessor=\"from\" targetAccessor=\"to\" valueAccessor=\"amount\"\n/\u003e\n```\n\n### Geographic Visualization\n\nChoropleth maps, flow maps, and distance cartograms with canvas rendering,\nzoom/pan, tile basemaps, and animated particles:\n\n```jsx\nimport { ChoroplethMap, FlowMap, DistanceCartogram } from \"semiotic/geo\"\n\n\u003cChoroplethMap\n  areas={geoJsonFeatures} valueAccessor=\"gdp\"\n  colorScheme=\"viridis\" projection=\"equalEarth\" zoomable tooltip\n/\u003e\n\n\u003cFlowMap\n  nodes={airports} flows={routes} valueAccessor=\"passengers\"\n  showParticles particleStyle={{ color: \"source\", speedMultiplier: 1.5 }}\n/\u003e\n\n\u003cDistanceCartogram\n  points={cities} center=\"rome\" costAccessor=\"travelDays\"\n  showRings costLabel=\"days\" lines={routes}\n/\u003e\n```\n\n### Streaming System Monitor\n\nLive service topology with threshold alerting and click-to-inspect:\n\n```jsx\nimport { StreamNetworkFrame, ChartContainer, DetailsPanel, LinkedCharts } from \"semiotic\"\n\nconst chartRef = useRef()\nchartRef.current.push({ source: \"API\", target: \"Orders\", value: 15 })\n\n\u003cLinkedCharts\u003e\n  \u003cChartContainer title=\"System Monitor\" status=\"live\"\n    detailsPanel={\n      \u003cDetailsPanel position=\"right\" trigger=\"click\"\u003e\n        {(datum) =\u003e \u003cdiv\u003e{datum.id}: {datum.value} req/s\u003c/div\u003e}\n      \u003c/DetailsPanel\u003e\n    }\u003e\n    \u003cStreamNetworkFrame ref={chartRef} chartType=\"sankey\"\n      showParticles particleStyle={{ proportionalSpeed: true }}\n      thresholds={{ metric: n =\u003e n.value, warning: 100, critical: 250 }}\n    /\u003e\n  \u003c/ChartContainer\u003e\n\u003c/LinkedCharts\u003e\n```\n\n### Standard Charts\n\nLine, bar, scatter, area — all the basics, with sensible defaults:\n\n```jsx\nimport { LineChart, BarChart } from \"semiotic\"\n\n\u003cLineChart\n  data={salesData}\n  xAccessor=\"month\" yAccessor=\"revenue\"\n  curve=\"monotoneX\" showPoints\n/\u003e\n\n\u003cBarChart\n  data={categoryData}\n  categoryAccessor=\"department\" valueAccessor=\"sales\"\n  orientation=\"horizontal\" colorBy=\"region\"\n/\u003e\n```\n\n## All Chart Components\n\n| Category | Components |\n|---|---|\n| **XY** | `LineChart` `AreaChart` `DifferenceChart` `StackedAreaChart` `Scatterplot` `ConnectedScatterplot` `BubbleChart` `Heatmap` `QuadrantChart` `MultiAxisLineChart` `MinimapChart` `CandlestickChart` `ScatterplotMatrix` |\n| **Categorical** | `BarChart` `StackedBarChart` `GroupedBarChart` `LikertChart` `SwimlaneChart` `FunnelChart` `SwarmPlot` `BoxPlot` `Histogram` `ViolinPlot` `RidgelinePlot` `DotPlot` `PieChart` `DonutChart` `GaugeChart` |\n| **Network** | `ForceDirectedGraph` `ChordDiagram` `SankeyDiagram` `ProcessSankey` `TreeDiagram` `Treemap` `CirclePack` `OrbitDiagram` |\n| **Geo** | `ChoroplethMap` `ProportionalSymbolMap` `FlowMap` `DistanceCartogram` |\n| **Realtime** | `RealtimeLineChart` `RealtimeHistogram` `RealtimeSwarmChart` `RealtimeWaterfallChart` `RealtimeHeatmap` |\n| **Coordination** | `LinkedCharts` |\n| **Layout** | `ChartGrid` `ContextLayout` `CategoryColorProvider` |\n| **Frames** | `StreamXYFrame` `StreamOrdinalFrame` `StreamNetworkFrame` `StreamGeoFrame` |\n\n### Vega-Lite Translation\n\nPaste a Vega-Lite spec, get a Semiotic chart:\n\n```jsx\nimport { fromVegaLite } from \"semiotic/data\"\nimport { configToJSX, fromConfig } from \"semiotic\"\n\nconst config = fromVegaLite({\n  mark: \"bar\",\n  data: { values: [{ a: \"A\", b: 28 }, { a: \"B\", b: 55 }] },\n  encoding: {\n    x: { field: \"a\", type: \"nominal\" },\n    y: { field: \"b\", type: \"quantitative\" },\n  },\n})\n\n// Render directly\nconst { componentName, props } = fromConfig(config)\n// → componentName: \"BarChart\", props: { data, categoryAccessor: \"a\", valueAccessor: \"b\" }\n\n// Or generate JSX code\nconfigToJSX(config)\n// → \u003cBarChart data={[...]} categoryAccessor=\"a\" valueAccessor=\"b\" /\u003e\n```\n\nSupports bar, line, area, point, rect, arc, tick marks with encoding translation\nfor color, size, aggregation, and binning.\n\n### Conversation Arc Telemetry\n\nCapture and replay the path an AI-assisted chart session took:\n\n```ts\nimport {\n  createLocalStorageConversationArcSink,\n  enableConversationArc,\n  getConversationArcStore,\n  loadConversationArc,\n  registerConversationArcSink,\n} from \"semiotic/ai\"\n\nconst sink = createLocalStorageConversationArcSink({ key: \"my-app:arc\" })\nregisterConversationArcSink(sink)\nenableConversationArc({ sessionId: \"session-abc\" })\n\ngetConversationArcStore().record({ type: \"chart-rendered\", component: \"LineChart\" })\nloadConversationArc(sink.load(), { enabled: false })\n```\n\n## Bundle Sizes\n\nSemiotic ships 12 entry points. **Don't import from `\"semiotic\"` unless you need everything** — use the sub-path that matches your chart type:\n\n\u003c!-- semiotic-bundle-sizes:start --\u003e\n\u003c!-- Auto-generated by `scripts/sync-bundle-sizes.mjs`. Edit dist/*, not this block. --\u003e\n\n| Entry Point | gzip | What's inside |\n|---|---|---|\n| `semiotic/xy` | **90 KB** | LineChart, AreaChart, Scatterplot, Heatmap, + 8 more XY charts |\n| `semiotic/ordinal` | **74 KB** | BarChart, PieChart, BoxPlot, Histogram, + 11 more categorical charts |\n| `semiotic/network` | **68 KB** | ForceDirectedGraph, SankeyDiagram, ProcessSankey, Treemap, + 4 more |\n| `semiotic/geo` | **55 KB** | ChoroplethMap, FlowMap, DistanceCartogram, ProportionalSymbolMap |\n| `semiotic/realtime` | **95 KB** | RealtimeLineChart, RealtimeHistogram, + 4 streaming charts |\n| `semiotic/server` | **127 KB** | renderChart, renderDashboard, renderToImage, renderToAnimatedGif |\n| `semiotic/utils` | **37 KB** | ThemeProvider, validators, serialization — no chart components |\n| `semiotic/recipes` | **9 KB** | Pure layout functions (waffle, marimekko, flextree, dagre, …) |\n| `semiotic/themes` | **4 KB** | Theme presets only (tufte, carbon, etc.) |\n| `semiotic/data` | **3 KB** | bin, rollup, groupBy, pivot, fromVegaLite |\n| `semiotic/value` | **6 KB** | BigNumber — focal-value KPI / scorecard (SingleValueFrame POC) |\n| `semiotic/ai` | **246 KB** | All 47 schema-backed charts + validation — optimized for LLM code generation |\n| `semiotic` | **203 KB** | Everything below (full bundle) |\n\n\u003c!-- semiotic-bundle-sizes:end --\u003e\n\n```jsx\n// Import from the sub-path, not from \"semiotic\"\nimport { LineChart } from \"semiotic/xy\"\nimport { BarChart } from \"semiotic/ordinal\"\nimport { SankeyDiagram } from \"semiotic/network\"\nimport { ChoroplethMap } from \"semiotic/geo\"\n```\n\n**Tree-shaking**: Each sub-path is a self-contained bundle with `\"sideEffects\": false`. Bundlers (webpack, Rollup, Vite, esbuild) will tree-shake unused exports. If you only use `LineChart` from `semiotic/xy`, the bar/pie/network code is never included.\n\n**When to use `\"semiotic\"`**: Only if your app uses charts from 3+ categories (XY + ordinal + network) and you'd rather have one import than three. The full bundle is roughly the sum of every sub-path bundle above — see the `semiotic` row of the table for the current number.\n\n## TypeScript\n\nBuilt with `strict: true`. Full type definitions ship with the package.\nGenerics for type-safe accessors:\n\n```tsx\ninterface Sale { month: number; revenue: number }\n\n\u003cLineChart\u003cSale\u003e\n  data={sales}\n  xAccessor=\"month\"    // TS validates this is keyof Sale\n  yAccessor=\"revenue\"\n/\u003e\n```\n\n## Server-Side Rendering\n\nAll chart components render SVG automatically in server environments — no\nspecial imports or configuration needed:\n\n```jsx\n// Works in Next.js App Router, Remix, Astro — same component, same props\nimport { LineChart } from \"semiotic\"\n\n// Server: renders \u003csvg\u003e with path/circle/rect elements\n// Client: renders \u003ccanvas\u003e with SVG overlay for axes\n\u003cLineChart data={data} xAccessor=\"date\" yAccessor=\"value\" /\u003e\n```\n\nFor standalone SVG/PNG/GIF generation (email, OG images, PDF, Slack), use the server entry point:\n\n```js\nimport { renderChart, renderToImage, renderToAnimatedGif } from \"semiotic/server\"\n\n// SVG — sync, no dependencies\nconst svg = renderChart(\"LineChart\", {\n  data, xAccessor: \"date\", yAccessor: \"value\",\n  theme: \"tufte\", title: \"Revenue Trend\",\n})\n\n// PNG — async, requires sharp\nconst png = await renderToImage(\"BarChart\", { data, ... }, { format: \"png\", scale: 2 })\n\n// Animated GIF — async, requires sharp + gifenc\nconst gif = await renderToAnimatedGif(\"line\", data, { ... }, { fps: 12 })\n```\n\n## MCP Server\n\nmcp-name: io.github.nteract/semiotic\n\nSemiotic ships with an [MCP server](https://modelcontextprotocol.io) that lets AI coding assistants render charts, diagnose configuration problems, discover schemas, read packaged AI guidance, and get chart recommendations via tool calls.\n\n### Setup\n\nAdd to your MCP client config (e.g. `claude_desktop_config.json` for Claude Desktop):\n\n```json\n{\n  \"mcpServers\": {\n    \"semiotic\": {\n      \"command\": \"npx\",\n      \"args\": [\"semiotic-mcp\"]\n    }\n  }\n}\n```\n\nNo API keys or authentication required. The server runs locally via stdio. HTTP mode is also available for inspectors and web clients: `npx semiotic-mcp --http --port 3001`.\n\n### Tools\n\n| Tool | Description |\n|------|-------------|\n| **`renderChart`** | Render a Semiotic chart to static SVG. Supports the components returned by `getSchema` that are marked `[renderable]`. Pass `{ component: \"LineChart\", props: { data: [...], xAccessor: \"x\", yAccessor: \"y\" } }`. Returns SVG string or validation errors with fix suggestions. |\n| **`getSchema`** | Return the prop schema for a specific component. Pass `{ component: \"LineChart\" }` to get its props, or omit `component` to list all 47 chart schemas. Components marked `[renderable]` are available through `renderChart`; realtime charts require a browser/live environment. |\n| **`suggestChart`** | Legacy sample-row recommender. Pass `{ data: [{...}, ...] }` with 1–5 sample objects plus optional broad intent/capability filters. |\n| **`suggestCharts`** | Capability-based recommender for bounded row data. Returns ranked chart suggestions with scores, reasons, caveats, import paths, and ready-to-use props. |\n| **`suggestStreamCharts`** | Recommend realtime charts from a stream schema, throughput, and retention hints. |\n| **`suggestDashboard`** | Build a multi-panel dashboard suggestion that covers distinct analytical intents. |\n| **`suggestStretchCharts`** | Recommend audience-literacy stretch picks from an `AudienceProfile`. |\n| **`repairChartConfig`** | Check whether a requested chart fits a dataset and return ranked alternatives when it does not. |\n| **`interrogateChart`** | Return a statistical summary and chart-aware context for answering natural-language questions with optional annotations. |\n| **`diagnoseConfig`** | Check a chart configuration for common problems — empty data, bad dimensions, missing accessors, wrong data shape, and more. Returns a human-readable diagnostic report with actionable fixes. |\n| **`reportIssue`** | Generate a pre-filled GitHub issue URL for bug reports or feature requests. Pass `{ title: \"...\", body: \"...\", labels: [\"bug\"] }`. Returns a URL the user can open to submit. |\n| **`applyTheme`** | List named theme presets or return ThemeProvider/CSS/token usage for a preset such as `{ name: \"tufte\" }`. |\n\n### Resources\n\n| Resource | Description |\n|----------|-------------|\n| **`semiotic://schema`** | Full machine-readable component schema JSON. |\n| **`semiotic://components`** | Component index showing renderable/browser-only status and MCP categories. |\n| **`semiotic://behavior-contracts`** | Agent-visible semantic rules for color precedence, required prop combinations, push refs, and renderability. |\n| **`semiotic://system-prompt`** | Compact AI instructions with import rules, chart props, SSR guidance, and pitfalls. |\n| **`semiotic://examples`** | Copy-paste chart examples by data shape. |\n\n### Prompts\n\n| Prompt | Description |\n|--------|-------------|\n| **`build-semiotic-chart`** | Reusable workflow for choosing a chart, reading schema, diagnosing props, and rendering a preview. |\n| **`debug-semiotic-chart`** | Reusable workflow for debugging invalid props, rendering failures, and issue reports. |\n\n### Example: get schema for a component\n\n```\nTool: getSchema\nArgs: { \"component\": \"LineChart\" }\n→ Returns: { \"name\": \"LineChart\", \"description\": \"...\", \"parameters\": { \"properties\": { \"data\": ..., \"xAccessor\": ..., ... } } }\n```\n\n### Example: suggest a chart for your data\n\n```\nTool: suggestChart\nArgs: {\n  \"data\": [\n    { \"month\": \"Jan\", \"revenue\": 120, \"region\": \"East\" },\n    { \"month\": \"Feb\", \"revenue\": 180, \"region\": \"West\" }\n  ]\n}\n→ Returns:\n  1. BarChart (high confidence) — categorical field (region) with values (revenue)\n  2. StackedBarChart (medium confidence) — two categorical fields (month, region)\n  3. DonutChart (medium confidence) — 2 categories — proportional composition\n```\n\n### Example: render a chart\n\n```\nTool: renderChart\nArgs: {\n  \"component\": \"BarChart\",\n  \"props\": {\n    \"data\": [\n      { \"category\": \"Q1\", \"revenue\": 120 },\n      { \"category\": \"Q2\", \"revenue\": 180 },\n      { \"category\": \"Q3\", \"revenue\": 150 }\n    ],\n    \"categoryAccessor\": \"category\",\n    \"valueAccessor\": \"revenue\"\n  }\n}\n→ Returns: \u003csvg\u003e...\u003c/svg\u003e\n```\n\n### Example: diagnose a broken config\n\n```\nTool: diagnoseConfig\nArgs: { \"component\": \"LineChart\", \"props\": { \"data\": [] } }\n→ Returns: ✗ [EMPTY_DATA] data is an empty array — Fix: provide at least one data point\n```\n\n### Example: report an issue\n\n```\nTool: reportIssue\nArgs: {\n  \"title\": \"Bug: BarChart tooltip shows undefined for custom accessor\",\n  \"body\": \"When using valueAccessor='amount', tooltip displays 'undefined'.\\n\\ndiagnoseConfig output: ✓ no issues detected.\",\n  \"labels\": [\"bug\"]\n}\n→ Returns: Open this URL to submit the issue: https://github.com/nteract/semiotic/issues/new?...\n```\n\n### CLI alternative\n\nFor quick validation without an MCP client:\n\n```bash\nnpx semiotic-ai --list         # list components with import paths and renderability\nnpx semiotic-ai --list --json  # machine-readable component index\nnpx semiotic-ai --schema GaugeChart\nnpx semiotic-ai --suggest '{\"data\":[{\"category\":\"A\",\"value\":10}],\"intent\":\"comparison\"}'\nnpx semiotic-ai --doctor       # validate component + props JSON\nnpx semiotic-ai --schema       # dump all chart schemas\nnpx semiotic-ai --compact      # compact schema (fewer tokens)\n```\n\n`--doctor` uses the full `diagnoseConfig` checks when `dist` is available and falls back to schema-only validation in clean source checkouts.\n\n## Where to find Semiotic for AI assistants\n\nSemiotic is indexed by AI-coding-agent documentation tools so your assistant (Claude Code, Cursor, Cline, Copilot, etc.) can pull current docs and tools without copy-paste:\n\n- **Context7** — [context7.com/nteract/semiotic](https://context7.com/nteract/semiotic) (configured via `context7.json`)\n- **DeepWiki** — [deepwiki.com/nteract/semiotic](https://deepwiki.com/nteract/semiotic)\n- **GitMCP** — [gitmcp.io/nteract/semiotic](https://gitmcp.io/nteract/semiotic) (exposes the repo as an MCP endpoint directly)\n- **Official MCP Registry** — search \"semiotic\" at [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io)\n- **Smithery** — [smithery.ai/server/nteract/semiotic](https://smithery.ai/server/nteract/semiotic)\n\nAgent-facing API surface:\n\n- **`CLAUDE.md`**, **`ai/schema.json`**, **`ai/behaviorContracts.cjs`** — bundled in the npm tarball (see `package.json#files`); agents that install Semiotic locally read these directly. `CLAUDE.md` is the quick-start cheat sheet (HOC props, push API, theming, usage notes); `ai/schema.json` is the JSON Schema for every chart's prop surface (47 charts); `ai/behaviorContracts.cjs` carries the agent-visible semantic rules (color precedence, push-mode requirements, ID-accessor contracts).\n- [**`semiotic.nteract.io/llms.txt`**](https://semiotic.nteract.io/llms.txt) + [**`/llms-full.txt`**](https://semiotic.nteract.io/llms-full.txt) — deployed at the docs site per the [llms.txt standard](https://llmstxt.org). Agents fetch the navigation map (`llms.txt`) or the full inlined docs (`llms-full.txt`) over HTTP; they're not part of the npm package itself.\n\n## Documentation\n\n[Interactive docs and examples](https://semiotic.nteract.io)\n\n- [Getting Started](https://semiotic.nteract.io/getting-started)\n- [Charts](https://semiotic.nteract.io/charts) — chart types with live examples\n- [Frames](https://semiotic.nteract.io/frames) — full Frame API reference\n- [Features](https://semiotic.nteract.io/features) — axes, tooltips, interaction, responsive behavior, and composition\n- [Annotations](https://semiotic.nteract.io/annotations) — first-class annotation types, design guidance, provenance, and lifecycle\n- [Cookbook](https://semiotic.nteract.io/cookbook) — advanced patterns and recipes\n- [Playground](https://semiotic.nteract.io/playground) — interactive prop exploration\n\n## Upgrading\n\n- [Migration Guide](./MIGRATION.md) — upgrading from v1.x or v2.x\n- [Changelog](./CHANGELOG.md) — full release history\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Our community follows the nteract\n[Code of Conduct](https://github.com/nteract/nteract/blob/main/CODE_OF_CONDUCT.md).\n\n## Acknowledgments\n\nDevelopment of this library owes a lot to Susie Lu, Jason Reid, James Womack,\nMatt Herman, Shelby Sturgis, and Tristan Reid.\n\nThe Sankey layout engine is based on [sankey-plus](https://github.com/tomshanley/sankey-plus)\nby [Tom Shanley](https://github.com/tomshanley), which improved on his earlier\n`d3-sankey-circular` with better cycle detection, hierarchical arc stacking,\nand dynamic extent adjustment.\n\n_Semiotic icon based on an icon by Andre Schauer._\n\n## License\n\n[Apache 2.0](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnteract%2Fsemiotic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnteract%2Fsemiotic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnteract%2Fsemiotic/lists"}