The Problem
Developers who want to embed financial charts quickly hit a maintainability wall: the codebase contains 36 circular‑import cycles and several files (e.g., src/model/chart-model.ts) that exceed 850 lines, making changes ripple widely and hard to reason about.
What This Does
Lightweight‑Charts is a collection of seven self‑contained projects that together deliver a fast, canvas‑based charting library. The core library lives in src/ (253 files, 247 code files) and exposes a minimal API (createChart, LineSeries, etc.) usable via npm or CDN. Supporting projects include plugin-examples/ (181 files, 134 code files) and indicator-examples/ (99 files, 54 code files) that demonstrate extensions, while website/ (380 files, 84 code files) provides the documentation and demo UI. The repository’s import graph resolves 996 internal modules with 1 768 edges; 93 modules live inside circular dependencies, and hubs such as src/model/series-options are imported by 74 other modules, giving it a high‑blast‑radius impact.
How It Is Wired
Execution starts at the library’s public entry point init defined in packages/create-lwc-plugin/src/index.ts:15, which reaches 401 functions and is called from a single place. The internal call graph shows the most‑invoked functions: options (82 callers), ensureNotNull (75), model (73), min (66), and timeScale (63). A representative edge chain is constructor → subscribe → _updateData → setData, illustrating how data flow propagates.
Hub modules that many others depend on include:
src/model/series-options(Ca 74, Ce 4, instability 0.05) – in a cycle withchart-modelandtime-data.src/model/chart-model(Ca 48, Ce 29, instability 0.38) – 859‑line file, high cognitive load.src/model/time-data(Ca 71, Ce 5, instability 0.07) – also in the same cycle.
Circular imports cost anyone modifying these files: a change to series-options can silently break chart-model and vice‑versa, requiring careful extraction of shared types or dependency inversion. Oversized files such as src/model/chart-model.ts, src/model/price-scale.ts, and src/model/time-scale.ts exceed 850 lines, and src/gui/chart-widget.ts shows max indentation depth 6, indicating deep nesting that hampers comprehension.
How To Use It
Setup
# Install the packaged library from npm
npm install lightweight-charts
# Or try the latest master build via pkg.pr.new
npm install https://pkg.pr.new/lightweight-charts@master
Configuration No environment variables or secret keys are required; the library reads chart options directly from the object passed to createChart.
Running it – a minimal demo (as shown in the README):
import { createChart, LineSeries } from 'lightweight-charts';
const chart = createChart(document.body, { width: 400, height: 300 });
const lineSeries = chart.addSeries(LineSeries);
lineSeries.setData([
{ time: '2019-04-11', value: 80.01 },
{ time: '2019-04-12', value: 96.63 },
{ time: '2019-04-13', value: 76.64 },
{ time: '2019-04-14', value: 81.89 },
{ time: '2019-04-15', value: 74.43 },
]);
The standalone CDN build (unpkg/lightweight-charts) creates window.LightweightCharts for script‑tag usage if a bundler is not desired.
Real‑World Use
In a typical dashboard, a backend streams tick data via WebSocket; the frontend receives {time, price} objects and calls lineSeries.setData(updatedData) to keep the chart responsive. Plugins (e.g., those in plugin-examples/) can add cross‑hair, legend, or context‑menu behavior without touching the core chart code, thanks to the well‑scoped src/api/chart-api.ts entry point (39 functions, 24 callees).
Code Health & Issues
- Measured analysis (static, 224 findings): 116 high‑severity soundness issues (import‑cycle members in
series-options.ts,time-data.ts,chart-model.ts), 108 medium cognitive‑load findings (oversized files, high branching density). Files such assrc/model/chart-model.ts(859 lines) andsrc/model/price-scale.ts(deep nesting) are flagged. - CODE HEALTH AUDIT (6 findings):
- [HIGH] Make CI invoke the test suite it has –
.github/workflowscurrently have no test command; adding a test step to an existing workflow would surface failures before merge. - [MEDIUM] Enable Dependabot or Renovate – 20 manifests lack an update bot; committing
.github/dependabot.ymlcovering npm and GitHub Actions would keep dependencies patched. - [MEDIUM] Install from the lockfile in CI –
npm installwith a committedpackage-lock.json; switching tonpm ci(oryarn install --immutable) ensures the exact locked dependency set is tested. - [MEDIUM] Gate pull requests on a dependency vulnerability scan – no dependency‑scan step exists; adding
dependency-review-actiononpull_requestwould catch known‑vulnerable packages early. - [MEDIUM] Review the install lifecycle script and disable scripts in CI –
postinstallscripts could fetch binaries from URLs; settingignore-scriptsin CI or moving work to an explicit build step mitigates risk. - [LOW] Set
timeout-minuteson workflow jobs – four jobs declare no timeout; adding realistic bounds prevents overlapping runs on a two‑hourly schedule.
The Bottom Line
The library delivers a tiny, high‑performance canvas charting solution that integrates easily via npm or CDN, and its plugin/indicator examples showcase extensibility. However, the codebase suffers from circular imports, oversized modules, and CI gaps that increase maintenance overhead. Teams comfortable with a modest refactor to break cycles and add proper CI will find it a solid choice for financial dashboards; others may need to allocate effort to restructure the model layer before large‑scale adoption.