Appearance
Chart.js libraries comparison
Chart.js is the most-installed canvas charting library on the web, and, unlike FullCalendar, it ships no official framework connectors. Every framework binding is a separate community project, and the quality varies wildly: React and Vue are served by large, healthy wrappers; Angular and Svelte have solid maintained ones; Solid's only option has been frozen since mid-2024; and Lit has no modern Chart.js wrapper at all.
Rozie's @rozie-ui/chartjs ships the same Chart to every framework in your stack: the same generic component (the type prop drives the whole controller set), the same three structured events, the same fifteen-verb imperative handle, the same external-HTML tooltip portal slot, and the same :plugins passthrough on React, Vue, Svelte, Angular, Solid, and Lit alike. Each framework installs a pre-compiled @rozie-ui/chartjs-* package with no Rozie toolchain required.
Every wrapper on this page, including Rozie's, drives the same chart.js engine, current major v4 (4.5.x). The engine is shared and well-maintained, so this comparison is purely about the per-framework binding layer: which frameworks have a binding at all, how current it is, and how consistent the events / imperative-handle / custom-tooltip story is across them.
Comparison matrix
Cell legend: ✓ = documented out-of-the-box · ✗ = not supported / not present · ~ = partial / consumer-glue-required / not documented. ("Not documented" is scored ~, never ✗: absence of documentation is not evidence of absence.)
| Wrapper | Frameworks | Latest published | Framework support | Structured events | Imperative handle | HTML-tooltip slot | Per-type components | Selective (tree-shakable) registration |
|---|---|---|---|---|---|---|---|---|
| Rozie @rozie-ui/chartjs | 6 — React + Vue + Svelte + Angular + Solid + Lit | pre-1.0, released together | R18+ / V3.4+ / Sv5 / Ng19+ signals / Solid / Lit | ✓ 3 uniform (click/hover/datasetClick, structured, composed) on all 6 | ✓ uniform $expose (15 verbs) on all 6 | ✓ portal slot on all 6 | ✓ 8 typed components + generic Chart, all 6 | ✓ consumer-registers + /auto entry (per-type tree-shakes on source leaves) |
| react-chartjs-2 | React | 5.3.1 · 2025-10 | React 16.8 – 19 | ~ options.onClick + getElement*AtEvent helpers (no React events) | ✓ ref → Chart.js instance | ✗ external-handler only (no React slot) | ✓ 8 typed + generic Chart | ✓ typed components auto-register their controller |
| vue-chartjs | Vue 3 | 5.3.4 · 2026-07 | Vue 3 (3.x+) | ✗ emits no Vue events | ✓ ref.chart → instance | ✗ external-handler only (canvas-fallback slot only) | ✓ 8 typed + generic + createTypedChart | ✓ manual ChartJS.register(...) |
| ng2-charts | Angular | 10.0.0 · 2026-03 (v8 = Ng19) | Angular ≥ 21 on v10; earlier majors cover 17 – 20 (no signals — @Input/OnChanges) | ✓ chartClick / chartHover (2, Angular only) | ✓ ViewChild(BaseChartDirective).chart | ✗ no ng-template tooltip | ~ one canvas[baseChart] directive (type input) | ✓ provideCharts(...) selective |
| svelte-chartjs | Svelte | 4.0.1 · 2026-03 | Svelte 5 | ~ getElement*AtEvent helpers (no Svelte events) | ✓ bind:chart → instance | ✗ external-handler only | ✓ 8 typed + generic | ✓ manual ChartJS.register(...) |
| solid-chartjs | Solid | 1.3.11 · 2024-07 (frozen) | Solid 1.7+ | ✗ none documented | ~ not documented | ✗ | ✓ typed + DefaultChart | ✓ manual register |
| Lit | — | — | no modern Chart.js wrapper exists | ✗ | ✗ | ✗ | ✗ | ✗ |
Weekly downloads (npm, snapshot 2026-08-03→08-09, a popularity datum rather than a quality verdict): react-chartjs-2 ≈4,320,888 · vue-chartjs ≈1,004,541 · ng2-charts ≈446,627 · svelte-chartjs ≈61,002 · solid-chartjs ≈12,894 · chartjs-web-components (the dead Lit option) ≈19 · Rozie @rozie-ui/chartjs: new.
All competitor facts were verified against the npm registry, the GitHub API, and each project's README / source / package.json on 2026-08-10; re-check the dates before relying on them.
Where Rozie wins today
First-class packages for all six frameworks, including the two the ecosystem leaves stagnant or empty. Chart.js has no official connectors, so the matrix is a patchwork: React (≈4.3M/wk) and Vue (≈1.0M/wk) are healthy; Angular (ng2-charts, ≈0.45M/wk) and Svelte (svelte-chartjs, Svelte-5-ready) are solid and current; Solid's only wrapper has been frozen since 2024-07 with no documented instance or event API; and Lit has no modern Chart.js wrapper at all (the only named package targets Chart.js 2.x / lit-element 1.x and was last touched in 2021). A team standardizing on Chart.js gets two big wrappers, two solid ones, one stagnant package, and one hole. Rozie fills the whole row with the same component.
A uniform, structured event surface. This is the single biggest capability difference. Chart.js click/hover handling fragments badly per framework: react-chartjs-2 and svelte-chartjs give you
options.onClickplus exportedgetElementAtEventhelper functions (no framework events); vue-chartjs emits no Vue events at all; ng2-charts is the only one with native framework events (chartClick/chartHover); Solid and Lit have none. Rozie surfaces three events,@click/@hover/@datasetClick, with structured payloads ({ event, elements, chart }, the hit elements already resolved viagetElementsAtEventForMode). Each is composed over any consumer-suppliedoptions.onClick/onHoverrather than clobbering it. One event shape to learn once, on any framework.The external-HTML tooltip as a first-class portal slot, everywhere. No competitor offers a framework-native tooltip slot or render-prop. On every one of them a custom HTML tooltip means hand-writing
options.plugins.tooltip.external, a DOM-building callback that lives outside the framework's rendering model. Rozie surfaces it as onetooltipportal slot that emits the framework's idiomatic consumer surface (React/Solid render-prop, Vue scoped-slot, Svelte snippet, Angularng-templatecontent-child, Lit slot bridge), fed the live tooltip model ({ title, body, dataPoints, opacity }). The slot is guarded: omit it and you get Chart.js's default canvas tooltip on every target. Because canvas owns its own paint, the external tooltip is the one place a framework-native fragment can render over the chart, so Rozie implements that one well.A uniform imperative handle. Every competitor exposes the Chart.js instance its own way: a React
refto the instance, vue-chartjs'sref.chart, ng2-charts'sViewChild(BaseChartDirective).chart, svelte-chartjs'sbind:chart, and nothing documented on Solid/Lit. Rozie's$exposehandle is the same fifteen verbs —getChart/updateChart/resizeChart/resetChart/renderChart/stopChart/clearChart/getActiveElements/setActiveElements/getDatasetMeta/isDatasetVisible/setDatasetVisibility/showDataset/hideDataset/toBase64Image(PNG export) — on every target, grabbed with each framework's native ref mechanism.getChart()returns the raw instance, so the full Chart.js API is always one hop away.Per-type components and selective registration, at parity with react-chartjs-2. Each package exports the eight per-type components (
Line/Bar/…/Bubble), each registering only its own controller set, alongside the genericChart, which no longer auto-registers (the consumer registers what they use, or imports the/autokitchen-sink entry). The bundled React/Solid/Lit packages expose a per-variant subpath for each typed component (@rozie-ui/chartjs-react/line,…/bar, …), each resolving to its own isolated chunk, so importing/lineships only Line's registration; the source-shipped Vue/Svelte/Angular packages tree-shake per-type imports natively. ThedatasetIdKeyprop and the a11yfallbackslot (in-canvas fallback content alongsideariaLabel) round out react/vue wrapper parity.Angular emitted in the signals idiom. ng2-charts, the dominant Angular wrapper, is a
canvas[baseChart]directive built on@Input()+OnChanges, not Angular's signals model. Rozie's@rozie-ui/chartjs-angularis a standalone component whose props are signalinput()s and whose reactivity runs througheffect(), the Angular-19+ idiom, with the same(click)/(hover)outputs andviewChild-grabbable handle.:pluginsconsumer-extensibility, applied uniformly. Chart.js plugins (datalabels, annotation, zoom, a custom crosshair) are passed per-instance through:plugins, with no per-plugin wrapper code and zero bundle cost for plugins you don't engage. This matches the per-instancepluginsprop the React/Vue/Svelte wrappers also offer; the parity point is that Rozie does it the same way everywhere.
What Rozie defers
React 19 and Svelte 5 are already covered upstream. Unlike the FullCalendar comparison, version currency is not a differentiator here:
react-chartjs-2@5.3.1already listsreact@^19in its peer range, andsvelte-chartjs@4.0.1already targets Svelte 5. Rozie installs cleanly against React 19 and Svelte 5 too, matching the ecosystem on currency rather than leading it. Rozie's advantage on React/Vue/Angular/Svelte is the uniform cross-framework surface.Single-framework ergonomics are not the contest. The matrix scores out-of-the-box, cross-framework capability. On its home framework each of these is a solid pick; for a single-React or single-Vue app,
react-chartjs-2/vue-chartjsare large, battle-tested libraries and the obvious choice. The case for Rozie is one component, with one events/handle/tooltip surface to learn, document, and migrate, including where the Solid wrapper is frozen and the Lit one doesn't exist.
Try it
The @rozie-ui/chartjs showcase + API reference documents the @rozie-ui/chartjs-* packages — one pre-compiled, per-framework install (npm i @rozie-ui/chartjs-react chart.js, etc.). The ChartScreenshotDemo source renders line, bar, and doughnut from the one generic Chart, and the ChartBehaviorDemo source drives runtime type-switching, the @click event, the :plugins passthrough, and the tooltip portal slot.