# chartjs-plugin-annotation: drawing boxes, lines, and labels onto a Chart.js canvas

> chartjs-plugin-annotation adds reference lines, boxes, points, labels, polygons, and ellipses to Chart.js 4 charts. Its one hard rule is that it must be registered globally, since it does not work as an inline plugin, and its older releases are pinned to specific Chart.js versions.

**chartjs/chartjs-plugin-annotation** — Annotation plugin for Chart.js

- Repository: https://github.com/chartjs/chartjs-plugin-annotation
- Stars: 625 · Forks: 377
- Language: JavaScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/chartjs-chartjs-plugin-annotation

## Six annotation primitives, all drawn onto the chart area

Chart.js draws data and leaves everything else to plugins, which is why the request for a threshold line or a highlighted band usually ends in a custom drawing plugin. chartjs-plugin-annotation is the community answer to that gap. The README states that the plugin draws lines, boxes, points, labels, polygons and ellipses on the chart area, and the intended users are front-end engineers who need reference ranges and labels layered over an existing chart rather than a separate chart type. The plugin ships as `chartjs-plugin-annotation` on npm under the MIT licence, with documentation published at www.chartjs.org/chartjs-plugin-annotation. The scope is deliberately narrow, which is what makes it useful: it does not touch your data model, it adds a layer of drawn objects on top of the scales you already have.

## Registration is mandatory because inline use is not supported

The first thing the README says, above the feature list, is that the plugin needs to be registered and does not function as an inline plugin. That single constraint shapes how you install it. An inline plugin in Chart.js is one declared inside a chart configuration, scoped to that chart, and the annotation plugin deliberately is not that. You register it globally, which means every chart in the application gains the plugin, including charts that will never carry an annotation. That is a real trade-off rather than a technicality: a global registration reaches into charts that other teams may own, and it is one more piece of shared setup that has to be consistent across the app. If your annotation need belongs to a single chart and you cannot accept a global registration, this plugin is the wrong choice, and no configuration in the README changes that.

## Line, bar, scatter, and bubble charts, with a special case for doughnut

The plugin is not limited to one chart type. The README says annotations work with line, bar, scatter and bubble charts that use linear, logarithmic, time, or category scales, which covers most of the cases where you want to mark a point in time or a threshold on a value axis. Scale handling is the part that decides whether an annotation lands where you expect, because an annotation anchored to a time scale has to be positioned on the time axis rather than on an index. Separately, the README describes a doughnut label annotation for adding contents, with text, an image, or a canvas, in the middle area of doughnut charts. That is the mechanism for the classic total-in-the-hole design, and it is deliberately narrow: it applies to doughnut charts, and the README does not describe an equivalent centre content feature for pie charts.

## Each Chart.js generation has its own plugin major

The version table in the README is the fastest way to pick the right package release, and it is easy to miss. For Chart.js 3.7.0 through 3.9.1 the README points to version 2.2.1 of the plugin. For Chart.js 3.0.0 through 3.6.2 it points to version 1.4.0. For Chart.js 2.4.0 through 2.9.x it points to version 0.5.7. The current line targets Chart.js 4.0.0 and later. In other words the plugin does not attempt to span every Chart.js major with one release; it ships a parallel major for each generation of the host library. The practical consequence is that a project upgrading Chart.js from 3 to 4 has to upgrade the plugin at the same time, and a project stuck on an older Chart.js needs to pin a plugin major that nobody has touched in years. The README also states the plugin needs to be registered separately, so the upgrade touches both your import and your registration code.

## The package ships ESM, CommonJS, and a browser script

The `package.json` describes a modern packaging setup with three entry points. The `main` field points at `dist/chartjs-plugin-annotation.cjs`, `module` at `dist/chartjs-plugin-annotation.esm.js`, and `types` at `types/index.d.ts`, so TypeScript consumers get declarations straight from the package. The `exports` map lists the same files per condition, with a `script` condition for the minified browser build that jsdelivr and unpkg serve:

```json
  "exports": {
    "types": "./types/index.d.ts",
    "import": "./dist/chartjs-plugin-annotation.esm.js",
    "require": "./dist/chartjs-plugin-annotation.cjs",
    "script": "./dist/chartjs-plugin-annotation.min.js"
  },
```

The package declares `"type": "module"`, which is why the CommonJS build carries the `.cjs` extension, and it lists the CommonJS and minified bundles in `sideEffects` so a bundler keeps them when tree shaking. The published `files` array is restricted to `dist/*` and `types/*.d.ts`, with the docs build excluded, so the documentation build does not ship inside the package. If you are consuming the plugin from a script tag rather than a bundler, the `script` condition is the path you want.

## Rolling up the bundle and running the tests in a browser

The build and test tooling is visible in the `scripts` section and the repository root, and it tells you what the project expects from contributors. The bundle is produced by Rollup with `rollup -c` and a `rollup.config.js` at the root. Tests run in real browsers through Karma, with a `karma.conf.cjs` file and separate scripts for an auto watching run in Chrome and one in Firefox:

```json
    "build": "rollup -c",
    "dev": "karma start ./karma.conf.cjs --auto-watch --no-single-run --browsers chrome",
    "dev:ff": "karma start ./karma.conf.cjs --auto-watch --no-single-run --browsers firefox",
```

Linting is split into JavaScript, Markdown, and TypeScript tasks, with the type task running `tsc -p types/tests/` against a dedicated type test directory, and the whole suite is driven by `concurrently` grouped tasks. The documentation is a VuePress site built from the `docs` directory with a separate `docs:dev` command. The repository also carries an `.eslintrc.yml`, an `.eslintignore`, an `.editorconfig`, and a `CONTRIBUTING.md` that the README asks contributors to read before opening an issue or a pull request. A coverage badge is wired to coveralls through the CI workflow.

## What the README does not tell you, and what the release history shows

Two gaps are worth naming before you commit. First, the README lists the annotation shapes and the supported chart types, but it says nothing about the configuration options for each shape: positions, colours, background, drawing order, and the annotation type identifiers all live on the documentation site rather than in the README. If you are the kind of team that prefers to read the source of truth in the repository, that documentation split is friction, and the `docs` directory in the repository is where the VuePress sources of those pages live. Second, the release cadence has slowed relative to the commits. The newest tagged release listed is v3.1.0 from 2024-10-16, with v3.0.1 in May 2023 and v3.0.0 a few days earlier, while the last push was on 2026-10-12. So there is recent work in the repository that has not produced a new tag, which is normal for this project but worth checking if you are pinning a version. The licence is MIT, which keeps adoption inside a commercial product straightforward.

## Conclusion

Use chartjs-plugin-annotation when you need thresholds, target bands, or callouts that Chart.js itself will not draw, and you are on Chart.js 4.0.0 or newer. Skip it if you want annotations that travel with a single chart instance, because the plugin refuses to work as an inline plugin and has to be registered for every chart on the page. Before you adopt it, check which Chart.js major version you are on against the version table, since the plugin keeps separate majors for the older Chart.js lines, and read the annotation options in the chartjs.org documentation because the README itself lists the shapes it draws but leaves their configuration to those pages.

## FAQ

### How do I add annotations to a Chart.js chart?

Install the `chartjs-plugin-annotation` package and register the plugin, because the README states that it needs to be registered and does not function as an inline plugin. The annotation options for each shape are documented on the chartjs.org documentation pages rather than in the README.

### Which version of chartjs-plugin-annotation should I use with Chart.js 3?

For Chart.js 3.7.0 to 3.9.1 the README points to version 2.2.1 of the plugin, and for Chart.js 3.0.0 to 3.6.2 it points to version 1.4.0. The current line of the plugin targets Chart.js 4.0.0 and newer.

### Which chart types and scales does chartjs-plugin-annotation support?

The README says annotations work with line, bar, scatter and bubble charts that use linear, logarithmic, time, or category scales. There is also a doughnut label annotation for placing text, an image, or a canvas in the middle area of doughnut charts.

### Can I use chartjs-plugin-annotation as an inline plugin?

No. The README states plainly that the plugin needs to be registered and that it does not function as an inline plugin, so it has to be registered for the application rather than attached to a single chart configuration.

### What licence is chartjs-plugin-annotation released under?

It is released under the MIT licence, with the license file named LICENSE.md at the repository root, and the npm package metadata also declares `"license": "MIT"`.

## Sources

- [chartjs/chartjs-plugin-annotation on GitHub](https://github.com/chartjs/chartjs-plugin-annotation)
- [Issues](https://github.com/chartjs/chartjs-plugin-annotation/issues)
- [License: MIT](https://github.com/chartjs/chartjs-plugin-annotation/blob/master/LICENSE)
- [README](https://github.com/chartjs/chartjs-plugin-annotation/blob/master/README.md)
- [Releases](https://github.com/chartjs/chartjs-plugin-annotation/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/chartjs-chartjs-plugin-annotation
