chartjs/Chart.js
Simple HTML5 Charts using the <canvas> tag
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3w ago
- ✓39+ active contributors
- ✓Distributed ownership (top contributor 27% of recent commits)
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the “Healthy” badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/chartjs/chart.js)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/chartjs/chart.js on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: chartjs/Chart.js
Generated by RepoPilot · 2026-05-06 · Source
Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/chartjs/Chart.js shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
Verdict
GO — Healthy across the board
- Last commit 3w ago
- 39+ active contributors
- Distributed ownership (top contributor 27% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live chartjs/Chart.js
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/chartjs/Chart.js.
What it runs against: a local clone of chartjs/Chart.js — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in chartjs/Chart.js | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 50 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of chartjs/Chart.js. If you don't
# have one yet, run these first:
#
# git clone https://github.com/chartjs/Chart.js.git
# cd Chart.js
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of chartjs/Chart.js and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "chartjs/Chart.js(\\.git)?\\b" \\
&& ok "origin remote is chartjs/Chart.js" \\
|| miss "origin remote is not chartjs/Chart.js (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "src/index.js" \\
&& ok "src/index.js" \\
|| miss "missing critical file: src/index.js"
test -f "src/core/core.controller.js" \\
&& ok "src/core/core.controller.js" \\
|| miss "missing critical file: src/core/core.controller.js"
test -f "src/core/core.datasetController.js" \\
&& ok "src/core/core.datasetController.js" \\
|| miss "missing critical file: src/core/core.datasetController.js"
test -f "src/scales/scale.js" \\
&& ok "src/scales/scale.js" \\
|| miss "missing critical file: src/scales/scale.js"
test -f "src/plugins/plugin.legend.js" \\
&& ok "src/plugins/plugin.legend.js" \\
|| miss "missing critical file: src/plugins/plugin.legend.js"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 50 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~20d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/chartjs/Chart.js"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
TL;DR
Chart.js is a lightweight JavaScript/TypeScript library that renders interactive, animated charts directly into HTML5 <canvas> elements. It provides bar, line, radar, doughnut, pie, and polar charts with built-in legends, tooltips, and responsive scaling—solving the need for simple, dependency-light charting without the complexity of D3 or commercial solutions. Single-package repository structure: core charting engine in the root src/ (likely), documentation in docs/ (VuePress-based, configured at docs/.vuepress/config.ts), build automation in auto/ directory (dual-format exports: CJS and ESM via auto.cjs, auto.js, auto.d.ts), and GitHub workflows in .github/workflows/ for CI, deployment, and releases.
Who it's for
Frontend developers and designers building dashboards, analytics UIs, and data visualizations who need charting that works in browsers without heavy framework dependencies. Specifically those using vanilla JavaScript, React, Vue, Angular, or Svelte who want charts that are easy to configure and customize.
Maturity & risk
Chart.js is production-ready and actively maintained. The codebase is ~1.22MB JavaScript with comprehensive TypeScript types (~148KB), sophisticated CI/CD pipelines across 5 GitHub Actions workflows, and version 4 is the current stable release (with docs for v2.9.4+ maintained). Regular releases via release-drafter.yml and active Discord community indicate ongoing support.
Low risk for established projects; the library is stable and widely adopted. Minimal risk around abandonment given the Discord community and active CI. Potential concerns: TypeScript conversion is ongoing (148KB of 1.37MB total is TS, rest is JS), so type coverage may be incomplete in some chart types. Breaking changes possible between major versions (v2→v3→v4) require careful migration planning.
Active areas of work
Active v4 development with VuePress documentation infrastructure maintained (docs structure spans axes types, configuration, chart types). Dependabot integration (dependabot.yml) suggests regular dependency updates. Release pipeline is automated (release-drafter, release.yml). The codebase is clearly under active use based on CI workflow presence.
Get running
git clone https://github.com/chartjs/Chart.js.git
cd Chart.js
npm install
npm run build
(Assuming npm/Node.js; check for package-lock.json or yarn.lock for specific package manager)
Daily commands:
npm run dev # Start dev server (inferred; check package.json scripts)
npm run build # Build distribution files
npm run test # Run test suite (likely Jest or Mocha, coverage via Coveralls)
npm run docs:dev # Start VuePress documentation server
(Exact commands require examining root package.json; workflows reference ci.yml, compressed-size.yml for build verification)
Map of the codebase
src/index.js— Main entry point that exports the Chart constructor and registers default chart types and plugins.src/core/core.controller.js— Core Chart controller managing initialization, updates, rendering, and lifecycle for all chart instances.src/core/core.datasetController.js— Base dataset controller handling data rendering logic shared across all chart types.src/scales/scale.js— Abstract scale class implementing axis logic for both cartesian and radial scales.src/plugins/plugin.legend.js— Official legend plugin providing dataset filtering and interaction; critical for user experience.src/plugins/plugin.tooltip.js— Official tooltip plugin handling hover interactions and data display across all chart types.package.json— Root manifest defining dependencies, build scripts, and version versioning for the entire library.
How to make changes
Add a new chart type
- Create chart controller extending core.controller.js with type-specific defaults and metadata (
src/charts/chart.{typename}.js) - Create dataset controller extending core.datasetController.js for rendering data points and shapes (
src/controllers/dataset.{typename}.js) - Define element types (point, line, arc, rectangle) in src/elements/ used for visual rendering (
src/elements/element.{shape}.js) - Register chart in src/index.js using Chart.register() or export from auto/auto.js (
src/index.js) - Add configuration documentation and example (
docs/charts/{typename}.md)
Add a custom plugin
- Create plugin object with id, lifecycle hooks (beforeInit, afterDraw, etc.), and options schema (
src/plugins/plugin.{name}.js or external file) - Register plugin using Chart.register(myPlugin) in user code or in src/index.js for built-ins (
src/index.js or user application) - Plugin receives chart instance; access data via chart.data, config via chart.options.plugins[id] (
plugin code accessing chart instance) - Document plugin API and options in docs/developers/plugins.md or docs/configuration/{name}.md (
docs/developers/plugins.md)
Add a new scale type
- Extend src/scales/scale.js implementing _parse(), _convert(), and _getLabelSize() methods (
src/scales/scale.{typename}.js) - Define tick generation logic in generateTicks() to compute axis labels (
src/scales/scale.{typename}.js) - Register scale using Chart.register() in src/index.js (
src/index.js) - Reference in axis config via type: '{typename}' in chart options.scales (
user chart options) - Document scale options and behavior (
docs/axes/cartesian/{typename}.md or docs/axes/radial/{typename}.md)
Add animation support to a new element
- Create new element extending src/elements/element.js with draw() method (
src/elements/element.{shape}.js) - Define animatable properties via getAnimationTarget() (e.g., radius, rotation, opacity) (
src/elements/element.{shape}.js) - Use element in dataset controller; core.animator.js automatically tweens properties via requestAnimationFrame (
src/controllers/dataset.{type}.js) - Users control via options.animation.duration, options.animation.easing config (
user chart options)
Why these technologies
- HTML5 Canvas API — Provides pixel-perfect 2D vector drawing without DOM overhead; essential for smooth animations and large datasets.
- requestAnimationFrame — Syncs animations with browser refresh cycles (60 FPS); avoids j
Traps & gotchas
- Dual export builds required: Changes to core code must be tested against both ESM (auto.js) and CJS (auto.cjs) outputs; watch for bundler-specific issues. 2. Canvas context assumptions: Chart rendering deeply couples to HTML5 Canvas 2D API; changes to rendering logic may break in offscreen canvas or server-side rendering scenarios. 3. Responsive canvas resizing: Charts use window.devicePixelRatio and resize observers; testing in different DPI environments (retina vs standard) is non-obvious but critical. 4. Plugin/axis registration: New chart types or axes must be registered in the auto.* files to be bundled; forgetting registration causes silent failures.
Architecture
Concepts to learn
- Canvas 2D Context API — Entire Chart.js rendering pipeline draws to HTML5
<canvas>via the 2D context; understanding transform matrices, clip regions, and state management is essential for debugging rendering bugs - Responsive Canvas Scaling (devicePixelRatio) — Charts must render crisply on retina displays; Chart.js internally scales canvas resolution by window.devicePixelRatio, and mismatches cause blurry charts or memory leaks
- Plugin Architecture / Hook System — Chart.js extends functionality via plugins (tooltips, legends, animations) that hook into lifecycle events; understanding beforeDraw, afterDraw, beforeDatasetDraw callbacks is critical for customization
- Categorical vs. Numerical Axis Scaling — Different chart types use different axis scale types (category for bar charts, linear/logarithmic for line, time-based for timeseries); axis type determines how data is mapped to canvas coordinates
- ES Modules with CommonJS Fallback (Dual Builds) — Chart.js publishes both ESM (auto.js) and CJS (auto.cjs) to support modern bundlers and legacy environments; build failures often stem from bundler-specific export resolution
- Animation Frame Scheduling (requestAnimationFrame) — Chart.js animations use RAF to sync with browser refresh rates; understanding frame timing and easing functions is needed for smooth animation behavior and performance optimization
- Data Structure Normalization — Chart.js accepts multiple input formats (arrays, objects, mixed) and normalizes them to internal data structures; bugs often arise from edge cases in parsing user-provided datasets
Related repos
apache/echarts— Full-featured charting alternative supporting more chart types and animations; competes on feature richness where Chart.js emphasizes simplicityplotly/plotly.js— Similar canvas/WebGL charting library with 3D support and scientific graphing; serves researchers and data scientists whereas Chart.js targets web dashboardschartjs/awesome— Official companion repo curating plugins, adapters, and examples for Chart.js; essential for extending core functionalityd3/d3— Predecessor/inspiration for low-level charting primitives; Chart.js exists as an abstraction layer atop D3 concepts for easier use
PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for auto-registration package (auto/)
The auto/ subdirectory contains critical auto-registration functionality (auto.js, auto.cjs, auto.d.ts) that bridges bundlers with and without exports support, but there are no visible test files for this package. This is high-value because the auto-registration is a key entry point for webpack 4 and similar bundlers, and any regression here breaks a significant portion of users.
- [ ] Create test/auto/auto.spec.js to test ES module exports from auto/auto.js
- [ ] Create test/auto/auto.cjs.spec.js to test CommonJS compatibility from auto/auto.cjs
- [ ] Add tests verifying all chart types (Line, Bar, Radar, Doughnut, Polar, Bubble, Scatter) are properly auto-registered
- [ ] Add tests to verify TypeScript definitions in auto/auto.d.ts are accurate
- [ ] Update CI workflow (if needed) to run auto package tests separately
Add missing documentation for plugin architecture in docs/configuration/
The docs/configuration/ directory contains extensive configuration files (animations.md, interactions.md, elements.md, etc.) but there is no visible documentation file for plugins, which is a core extensibility feature in Chart.js. This is a concrete gap that blocks plugin developers from understanding the plugin API.
- [ ] Create docs/configuration/plugins.md documenting the plugin lifecycle hooks (afterInit, beforeUpdate, afterUpdate, etc.)
- [ ] Document the plugin registration API and configuration options
- [ ] Add code examples showing how to create and register custom plugins
- [ ] Link to docs/configuration/plugins.md from docs/configuration/index.md
- [ ] Document the plugin context object and available methods (e.g., chart instance access)
Create GitHub Actions workflow for dependency vulnerability scanning
The .github/workflows/ directory has ci.yml, release.yml, and deploy-docs.yml, but there is no dedicated security scanning workflow. The dependabot.yml exists, but there's no active workflow to scan for CVEs in dependencies and alert maintainers during CI. This is high-value for a widely-used library where security issues directly impact downstream users.
- [ ] Create .github/workflows/security-scan.yml using GitHub's native CodeQL or a tool like snyk/action-codeql
- [ ] Configure the workflow to run on every push to master and on pull requests
- [ ] Set up notifications/failure conditions for discovered vulnerabilities
- [ ] Update MAINTAINING.md with instructions on responding to security scan results
- [ ] Document the security scanning process in .github/SECURITY.md (if it doesn't exist)
Good first issues
- Add TypeScript types to remaining JavaScript files in
src/(~50% TS coverage remains); start by converting a single chart class likesrc/chart/doughnut.jsto.tsand updating auto.d.ts exports. - Expand
docs/axes/cartesian/documentation: the time and timeseries axis docs lack example configurations and common gotchas; add practical examples mirroring the format in linear.md and category.md. - Create test coverage for edge cases in responsive canvas resizing: write tests in
test/(inferred) validating chart behavior whenwindow.devicePixelRatiochanges or canvas is in a hidden DOM node before initialization.
Top contributors
- @LeeLenaleee — 27 commits
- @dependabot[bot] — 15 commits
- @joshkel — 9 commits
- @bojidar-bg — 4 commits
- @marisst — 3 commits
Recent commits
ab79c3b— Corrected spacing in pie/doughnut/polarArea (Fixes #10059) (#12238) (danielgindi)a153556— Bump actions/checkout from 4 to 6 (#12160) (dependabot[bot])6d4bf67— Bump js-yaml from 3.14.1 to 3.14.2 (#12159) (dependabot[bot])2898a6d— Use integer canvas dimensions (#12142) (joshkel)e8c58da— Enable scale title stroke (12092) (#12130) (asmenezes)2bbb96c— docs: Add note about flexbox/grid layout responsivity issue (#12134) (DrWarpMan)67f67ae— Bump actions/setup-node from 5 to 6 (#12138) (dependabot[bot])f6310f2— Fix amount of category scales count in docs (#12139) (LeeLenaleee)72c6742— Bump pnpm/action-setup from 4.1.0 to 4.2.0 (#12133) (dependabot[bot])9c5cf9f— Bump version to 4.5.1 (#12132) (LeeLenaleee)
Security observations
Chart.js demonstrates a reasonable security posture for a popular open-source charting library. The project uses modern CI/CD practices with GitHub Actions and Dependabot integration. However, there are opportunities for improvement: implementing security headers in the documentation site, establishing a formal vulnerability disclosure policy, and enhancing automated security scanning. The primary risk area is ensuring user-supplied data (especially labels and tooltips) is properly sanitized to prevent XSS attacks. No critical vulnerabilities were identified in the provided configuration files, but proactive security measures would further strengthen the project's security maturity.
- Medium · Missing Security Headers in Documentation Site —
docs/.vuepress/config.ts. The VuePress documentation configuration (.vuepress/config.ts) may lack security headers like Content-Security-Policy, X-Frame-Options, and X-Content-Type-Options. This could expose the documentation site to XSS attacks and clickjacking vulnerabilities. Fix: Add security headers configuration to the VuePress config file. Configure meta tags for CSP and ensure proper HTTP headers are set on the hosting platform. - Low · Potential XSS Risk in Chart Rendering —
src/core/ (entire charting engine). Canvas-based chart libraries like Chart.js can be vulnerable to XSS if user-supplied data is rendered without proper sanitization. While Chart.js primarily uses canvas (which is safer than DOM manipulation), label text and tooltips could potentially be exploited if they accept HTML content. Fix: Ensure all user-supplied data inputs (labels, tooltips, datasets) are properly sanitized and never directly rendered as HTML. Validate and escape all text content before display. - Low · Missing SECURITY.md File —
Repository root. The repository does not appear to have a SECURITY.md file for vulnerability disclosure policies, which is a best practice for popular open-source projects with many users. Fix: Create a SECURITY.md file that outlines the vulnerability disclosure process, security contact information, and expected response times for security reports. - Low · Dependabot Configuration Could Be Enhanced —
.github/dependabot.yml. While Dependabot is configured (.github/dependabot.yml), there's no evidence of strict security update policies or automated security scanning workflows beyond standard CI/CD. Fix: Enhance Dependabot configuration with security-only update schedules. Add automated security scanning tools like npm audit, OWASP Dependency-Check, or Snyk to the CI/CD pipeline. - Low · No Visible Code Signing or Integrity Verification —
.github/workflows/release.yml. The release workflow (.github/workflows/release.yml) does not appear to include code signing or provenance verification mechanisms, which helps users verify package authenticity. Fix: Implement signed releases using GPG signatures or tools like Sigstore for npm packages. Publish provenance information to help consumers verify package integrity.
LLM-derived; treat as a starting point, not a security audit.
Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.