leeoniya/uPlot
47.6
Weak · 2 October 2026
21.8k
lines of production code
JavaScript
primary language
2
measurements over time
What this system is
uPlot is a high-performance JavaScript charting library that renders line, bar, and band charts with a focus on speed and precision. It provides extensive configuration for axes, scales, and data interpolation, alongside utilities for benchmarking and complex visualizations like bar charts. The system includes a comprehensive suite of demos and tests to validate rendering logic and performance against other popular charting libraries.
How it got here
2019 — Rebranding to uPlot and build modernization
8 changes.
The project was renamed from Plotty to uPlot, introducing a new DOM structure, CSS classes, and a modernized build system using Rollup 4 and native ES modules. This period also involved expanding the demo suite with new examples, consolidating data files, and adding a comprehensive benchmark suite to compare performance against other charting libraries.
2020–2026 — Charting engine enhancements and tooling
5 changes.
This period focused on expanding the charting library's capabilities with new bar chart plugins, advanced interpolation algorithms, and comprehensive test coverage. Development efforts also included creating detailed issue reproduction demos and establishing a suite of benchmarking scripts to monitor performance and guide optimization.
Features
Added development and benchmarking scripts
This change introduces a suite of new Node.js scripts to the \scripts/\ directory to support development, testing, and performance analysis. The \bench-\*\ scripts (\bench-fixed-dec\, \bench-hover\, \bench-hover-browser\, \bench-join\, \bench-legend\, \bench-legend-browser\, \bench-range-layout\, \bench-rounding\) provide microbenchmarks and browser-based performance tests for core library functions like decimal rounding, hover handling, data joining, legend rendering, and range layout. Additionally, \audit-grafana-scales.mjs\ serves as an audit artifact to compare current scale builder behavior against historical Grafana implementations, while \demoSteps.mjs\ and \demos.mjs\ provide utilities for managing and serving demo snapshots.
scripts · high confidence
Added sample datasets for demos
The demos/data directory now includes CSV files for major tech stocks (AAPL, AMD, AMZN, CSCO, FB, MSFT, QCOM, SBUX, TSLA, ZNGA) containing daily OHLCV data from October–November 2019, a mass spectrum dataset (ms\_spectrum.csv), and a JSON file (results.json) with benchmark performance results for various JavaScript frameworks.
demos/data · high confidence
Expanded benchmark suite with new third-party charting libraries
The benchmark directory now includes performance demo pages for ApexCharts, CanvasJS, D3 v7.9.0, ECharts v6.1.0, Flot, Highcharts (with Boost module), LightningChart® JS v4.0.2, Plotly.js v2.18.2, ZingChart, and amCharts5, alongside updated demos for Chart.js v4.5.1. These additions allow users to compare rendering performance against a wider range of popular JavaScript charting libraries using the same server metrics dataset.
bench · high confidence
New demo utilities and bar chart plugin
Added several new helper libraries for demos, including a Fast Fourier Transform implementation (ASAP-optimized.js), data smoothing tools (ASAP-simple.js, double-mad.js, dbscan1d.js), and a distribution calculator (distr.js). Introduced a comprehensive bar chart plugin (barChartPlugin.js) that supports vertical and horizontal orientations, configurable group and bar distributions (SPACE\_BETWEEN, SPACE\_AROUND, SPACE\_EVENLY), bar width controls, value labels, and hover interactions. Also added supporting files for bar controls (barControls.js), hover handling (barHover.js), and value rendering (barValues.js), along with a D3 canvas alignment utility (d3CanvasAligned.js) for comparative demos.
demos/lib · high confidence
Behavioural changes
Demo data consolidated into a single JSON file
The demo's dataset has been merged from multiple individual JSON files into a single \data.json\ file. This change simplifies the data structure for the demo, likely reducing the number of network requests or file operations required to load the visualization data.
demo · high confidence
Library renamed from Plotty to uPlot with build and configuration updates
The library has been renamed from Plotty to uPlot, reflected in the source file (src/uPlot.js), the public API namespace, and the distribution outputs (uPlot.esm.js, uPlot.cjs.js, uPlot.iife.js). The build system has been updated to use @rollup/plugin-terser instead of the deprecated rollup-plugin-terser, and the JavaScript transpiler has switched from buble to native ES modules. Additionally, new configuration files have been added: .editorconfig for consistent coding style, jsconfig.json for IDE support, bunfig.toml for the Bun runtime, and a new bun.lock dependency lockfile.
(repo-wide) · high confidence
Library renamed to uPlot with new DOM structure and CSS classes
The library has been renamed from Plotty to uPlot. This introduces a new DOM structure and CSS class names (prefixed with \u-\), a new \uPlot.css\ stylesheet, and a new \dom.js\ module for DOM utilities. The old \plotty.js\ and \plotty.css\ files have been removed.
src · high confidence
New and updated demo applications
The demos directory has been significantly expanded and modernized with new examples including Add/Delete Series, Annotations, ArcSinh Scales, Axis Autosize, Axis Control, Axis Indicators, Axis Label Rotation, and Axis Range Alignment. Many demos have been refactored to use the new \renderDemo\ harness and ESM module imports, while others have been updated to reflect API changes such as \series.stroke\ and \opts.padding\.
demos · high confidence
New issue reproduction demos for scale range and scan behavior
Added eight new HTML demos in the \demos/issues\ directory that reproduce specific GitHub issues related to uPlot's scale configuration. These examples illustrate how to configure \scan\ (to disable or customize Y extrema scans), \auto\ (to control automatic range recalculation during zooms and resets), and \range\ (for static or dynamic bounds). The demos cover scenarios such as dynamic backend ranges, per-instance export resolution, automatic reset versus explicit zoom, candidate range calculation, fixed auto-false bounds, fixed-range boundary strokes, full-domain scanning, and resetting static ranges.
demos/issues · high confidence
Refactored path builders with new interpolation and bar rendering capabilities
The path-building logic in src/paths has been restructured into modular, purpose-specific files (bars, linear, stepped, spline, points) to improve maintainability and performance. This change introduces a new monotone cubic spline interpolation algorithm (replacing the previous centripetal Catmull-Rom variant) to prevent overshooting in line charts. A completely rewritten bars path builder now supports advanced features including configurable bar radius, custom alignment, gap handling, and per-bar fill/stroke colors via the disp option. Additionally, the stepped path builder gained new options to extend lines to plot extents and control ascender/descender rendering at gap boundaries.
src/paths · high confidence
Test coverage
Expanded test coverage for axis ranging, asinh transforms, and band drawing
Added comprehensive regression tests for the charting library's axis and rendering logic. The suite verifies adaptive asinh scale transforms and label thinning, decimal precision handling for axis labels, and the geometric correctness of band drawing and bar chart plugins. It also includes tests for axis range policies, label rotation, and cursor marker alignment to ensure consistent behavior across different pixel ratios and data configurations.
test · high confidence
Dependencies
Upgrade to uPlot v1.6.32 with modernized build tooling
The project has been renamed from plotty to uPlot and updated to version 1.6.32, shifting the build system from Rollup 1 to Rollup 4.63.4 and replacing legacy plugins like rollup-plugin-buble and rollup-plugin-terser with @rollup/plugin-terser. The test infrastructure has been significantly expanded, introducing Mocha 12.0.2 and Happy DOM 20.14.5 for server-side testing, alongside Istanbul for code coverage, replacing the previous placeholder test script. The package is now configured as an ES module with explicit type definitions and a broader set of keywords.
(dependencies) · high confidence
uPlot updated to v1.6.32
The distribution files in dist/ have been updated to version 1.6.32 of the uPlot charting library. This release includes the latest build artifacts (CommonJS, ESM, and IIFE formats) along with updated TypeScript definitions, incorporating recent fixes and improvements to the library's core functionality.
dist · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 48 → 48 (-0.8)
- Rubric changed (rubric-2026.09.12 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 46 → 48 (+1.6)
- Architecture 96 → 98 (+1.6)
- Maturity 51 → 49 (-1.5)
- Readiness 36 → 38 (+1.4)
- Security 100 → 100 (-0.1)
- Performance 60 (new)
Resolved (23)
- (anonymous) (cognitive 18) (scripts2/bench-hover.mjs)
- Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (no pnpm-resolved versions to grade)
- Documentation: no installation or build instructions (README.md)
- FunctionTooLong: probe-worker.createProbeWorker (scripts2/probe-worker.mjs)
- Hotspot: test/layout.mjs (test/layout.mjs)
- bars (cognitive 88) (src/paths/bars.js)
- bars (cyclomatic 56) (src/paths/bars.js)
- bench-hover-browser.runCase (cognitive 16) (scripts2/bench-hover-browser.mjs)
- bench-hover.server (cognitive 18) (scripts2/bench-hover.mjs)
- bench-join.previousJoin (cognitive 32) (scripts2/bench-join.mjs)
- createProbeWorker (cognitive 34) (scripts2/probe-worker.mjs)
- createProbeWorker (cyclomatic 30) (scripts2/probe-worker.mjs)
- opts.asinhScale (cognitive 25) (src/opts.js)
- scanScale::acc (cognitive 23) (src/uPlot.js)
- stepped (cognitive 36) (src/paths/stepped.js)
- stepped (cyclomatic 28) (src/paths/stepped.js)
- uPlot.scanScale (cognitive 55) (src/uPlot.js)
- uPlot.scanScale (cyclomatic 30) (src/uPlot.js)
- uPlot::initLegendRow (cognitive 21) (src/uPlot.js)
- uPlot::setData (cognitive 18) (src/uPlot.js)
- …and 3 more
New (95)
- Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (the committed lockfile resolved no direct production dependency)
- Documentation: contradicts the code (docs/investigations/hover-performance.md)
- Documentation: contradicts the code (docs/investigations/issue-20-export-pxratio.md)
- Documentation: contradicts the code (docs/investigations/minimal-axis-ranging-plan.md)
- Documentation: no architecture or design documentation (docs/investigations/scale-range-policy.md)
- Documentation: no project overview (docs/investigations/scale-range-issue-review.md)
- FunctionTooLong: bench-legend.benchmark (scripts/bench-legend.mjs)
- FunctionTooLong: legend-dom-template.createLegendTemplate (src/legend-dom-template.js)
- FunctionTooLong: probe-worker.createProbeWorker (scripts/probe-worker.mjs)
- Hotspot: demos/lib/barChartPlugin.js (demos/lib/barChartPlugin.js)
- Hotspot: demos/lib/barControls.js (demos/lib/barControls.js)
- Hotspot: src/paths/bars.js (src/paths/bars.js)
- Hotspot: src/rangeY.js (src/rangeY.js)
- Hotspot: test/axis-label-rotation-demo.mjs (test/axis-label-rotation-demo.mjs)
- Hotspot: test/range-y-chart-poc.mjs (test/range-y-chart-poc.mjs)
- Low CVE: [GHSA redacted] (bun.lock)
- No assertions: imports without DOM globals (test/keyed-list.mjs)
- No assertions: rejects nonfinite and invalid tick bounds without looping (test/asinh.mjs)
- Skipped (documented): clears obsolete marker styles and preserves rows, headers, and lazy bindings across marker modes (test/legend-contracts.mjs)
- Skipped (documented): delSeries accepts a custom cursor points.show returning no HTMLElement (test/master-lifecycle-bugs.mjs)
- …and 75 more
Changes since last survey
- 56 commits — 52 feature/other, 4 fixes
By area
- dist/uPlot.cjs.js — 12 commits
- test/demos — 10 commits
- demos/lib — 7 commits
- dist/uPlot.d.ts — 4 commits
- docs/investigations — 4 commits
- (root) — 3 commits
- demos/axis-range-aligned.html — 2 commits
- demos/axis-range-policies.html — 2 commits
- demos/index.html — 2 commits
- demos/axis-control.js — 1 commit
- demos/axis-label-rotation-chartjs.html — 1 commit
- demos/axis-label-rotation.html — 1 commit
- demos/bars-values-autosize.html — 1 commit
- demos/log-time-axis.js — 1 commit
- demos/soft-minmax.html — 1 commit
- demos/stacked-series.js — 1 commit
- dist/uPlot.esm.js — 1 commit
- src/paths — 1 commit
- src/uPlot.js — 1 commit
Notable commits
- fix: fix numDec to use splits array
- fix: fix setRange typings to include null bounds
- fix: fix stack demo point hover
- fix: fix ts export in typedef
- change: Add tick-aware Y ranging PoC and reuse extrema on redraw
- change: add bar distribution control to plugin & demo
- change: add ctxAttrs opt to allow pass-thru of canvas context constructor opts
- change: add echarts and chartjs bar demos
- change: add hz bar demo, allow scale.axis to apply to hz y scales
- change: add label rotation demo
- change: add linkable random seed to bars demo
- change: add opt-in for forcing start-of-month ticks with multi-day incrs
- change: add options to disable all dom besides the canvas (e.g. sparklines)
- change: add scale padding support for tick-aware (scale.axis) raning
- change: add soft and hard limit demo
- change: add u.setRange(scaleKey, min, max), simplify internals
- change: axis tick density work, decimal-aware tick formatters
- change: barchart fixups and cursor hover point invalidation
- change: better bar chart controls integration
- change: better bar demo
- …and 36 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
leeoniya/uPlot was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 2 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit e62f123fbd919ba56866bf34b37922d5d1f679e7 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.