vue-chartkick: one line of Vue for a Chart.js, Google or Highcharts chart
Create beautiful JavaScript charts with one line of Vue
At a glance
- What is it?
- vue-chartkick is a thin Vue 3 wrapper that turns a data prop into a rendered chart, backed by Chart.js, Google Charts or Highcharts, so a line chart is a single template tag with an object of dates and values. It also handles the awkward parts, such as numeric formatting, remote data endpoints and download of the rendered image.
- Who is it for?
- vue-chartkick is worth taking for a Vue 3 dashboard or admin panel, because it removes the boilerplate of instantiating a chart library and keeps it in sync with the component tree, which is the part people get wrong when they wire a chart library up by hand. It is the wrong tool if you need chart types outside the list, if you want to own the rendering lifecycle completely, or if you are on Vue 2, since that line lives on version 0.6.1 with its own readme and branch.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A chart is a template tag with a data prop
vue-chartkick describes itself as a way to create beautiful JavaScript charts with one line of Vue, and the line in question really is one line. A line chart with two data points is:
<line-chart :data="{'2026-01-01': 11, '2026-01-02': 6}"></line-chart>A pie chart is equally short, and the shape of the data changes with the chart type. A pie chart takes an array of label and value pairs, a column chart takes an array of category and value pairs, and a scatter chart takes pairs of coordinates with axis titles:
<scatter-chart :data="[[174.0, 80.0], [176.5, 82.3]]" xtitle="Size" ytitle="Population"></scatter-chart>The list of components covers line, pie, column, bar, area and scatter, plus geo chart and timeline, and the README marks the last two as Google Charts only. The geo chart takes country names and values, and the timeline takes a name and a start and end date, which is the component for showing a Gantt-like span.
Multiple series are handled by passing an array of objects rather than a plain array, where each entry carries a name and its own data:
data = [
{name: 'Workout', data: {'2026-01-01': 3, '2026-01-02': 4}},
{name: 'Call parents', data: {'2026-01-01': 5, '2026-01-02': 3}}
];The single-series form is a case of the same structure with the name omitted, which is why a chart component does not need a separate prop to switch between one and many series.
The package is MIT licensed and JavaScript, with a version of 1.1.0, and it depends on chartkick at 3.2.0 or above with Vue 3.0 or above as a peer dependency. The build is a single rollup command, and the published files are the dist directory with separate CommonJS and ES module entry points.
Three backing libraries, and the options differ between them
The wrapper does not implement a charting engine. It sits on top of one of three, Chart.js, Google Charts or Highcharts, and the choice decides which options are available.
The quick start shows the Chart.js route, which is the default: install the wrapper and the library, then register it on the app.
npm install vue-chartkick chart.jsimport VueChartkick from 'vue-chartkick'
import 'chartkick/chart.js'
app.use(VueChartkick)The import of chartkick/chart.js is the piece that selects the backing library, so switching between the three is a change of that import line rather than a change to every chart in the app.
Because the features are not uniform, the README annotates individual options with the library they apply to. Prefix and suffix, which is how you format currency and percentages, are marked as Chart.js and Highcharts. The thousands separator, the decimal separator, the significant digits option, the rounding option and the option that shows insignificant zeros are the same set. The bytes option, which renders friendly byte sizes, is marked as Chart.js 2.8 and later.
Two features are narrower still. The x-axis min and max options are Chart.js only, and the download option is Chart.js only, which the README explains as happening entirely in the browser with no server-side code needed. That one lets users save the rendered chart, with a filename of your choosing and a background colour you can set, and it carries a caveat: Safari will open the image in a new window instead of downloading it.
The min and max value options are generic. The README notes that min defaults to 0 for charts with non-negative values, and that you use null to let the charting library decide, which is the setting you want on a chart with negative values.
Data can be a literal, a callback or a URL endpoint
The data prop accepts four shapes, and the choice is a design decision about when the data arrives.
An array of pairs and an object of key to value are the literal forms, and they are what the chart examples use. A callback is the asynchronous form, and the signature is the one Chartkick has always used, with a success function and a fail function:
function fetchData(success, fail) {
success({"2026-01-01": 2, "2026-01-02": 3})
// or fail("Data not available")
}A URL is the fourth form, and the README is enthusiastic about it: make your pages load super fast and stop worrying about timeouts, give each chart its own endpoint.
<line-chart data="/stocks"></line-chart>The reasoning behind the URL form is that the chart renders immediately with no data and fills in when the request resolves, so a slow endpoint does not hold up the page, and each chart fetches only what it needs rather than one big payload feeding every chart on the page.
The same trade-off applies to the refresh option, which reloads data from a remote source every n seconds:
<line-chart :refresh="60"></line-chart>A URL and a refresh interval together are the standard way to build a live operational panel, and they are also where the wrapper is doing real work for you, since a chart that is fed by a callback on a timer has to be re-rendered and the previous series replaced, and that is exactly the kind of bookkeeping that goes wrong when it is hand written.
For empty and loading states there are two plain text options, the loading message shown while a request is in flight and the empty message shown when there is nothing to draw, which is worth setting because the default behaviour is whatever the backing library does with an empty dataset.
Formatting options cover currency, percentages and byte sizes
A surprising amount of a dashboard chart is the axis labels, and the wrapper exposes a set of formatting options rather than leaving you to write a formatter.
The value axis accepts a prefix and a suffix, which the README suggests for currency and for percentages respectively, along with a thousands separator, a decimal separator, a precision setting for significant digits and a round setting for decimal places. Those two together are the currency case: rounding to two places while showing insignificant zeros is what makes an amount read as an amount rather than a number.
<line-chart :round="2" :zeros="true"></line-chart>The bytes option converts the values into friendly byte sizes, marked as Chart.js 2.8 and later.
Beyond the numbers there are presentation options that matter more than they sound. The curve option turns the line between points from a curve into straight segments, which is the difference between a chart that smooths over a discontinuity and one that shows the jump. The discrete option turns a continuous axis into discrete steps, which is what you want for counts that only change at intervals. The legend option toggles the legend and the legend attribute positions it, with bottom given as an example. The donut option turns the pie chart into a ring. The label option names a single series, which is needed when the chart has one series and no legend.
Axis titles are set with xtitle and ytitle, and the id, width and height attributes are plain HTML attributes on the component, so a chart can be sized and identified the same way any other element is.
The escape hatch for anything not covered is the library option, which passes options straight to the backing library:
<line-chart :library="{backgroundColor: '#eee'}"></line-chart>Chart.js datasets can be customised separately with a dataset option, and the README notes it can be passed to individual series as well, so per-series styling is possible where the backing library supports it.
The reactivity warning in the README is the one thing to get right
There is a short section on reactivity that deserves to be read before you write any charts, because the failure it prevents is invisible.
The README notes that while some of the examples use object or array literals in props for demonstration, this can lead to unnecessary re-renders. The example it gives is the library option with an inline object. The fix is to use a data property instead:
<line-chart :library="library"></line-chart>The reason is that Vue's reactivity compares values to decide what to update, and an object literal written inline in a template is a new object on every render. The chart component therefore receives a prop that is never equal to the previous one, and it re-renders the chart each time, even when the contents are identical. On a dashboard with a chart that updates on a timer, that is a chart being torn down and rebuilt on every tick for no reason.
The README links to a discussion on the Vue issue tracker about this pattern, which is the kind of reference worth following if the behaviour surprises you.
The same discipline applies to the data prop itself, and it explains why the multiple series example above assigns to a variable rather than inlining the array. A chart fed from a reactive data property gets updated only when the data actually changes, and a chart fed from a literal gets updated constantly.
There is also a way to make the chart type itself dynamic, using the dynamic component syntax with a component element and an is attribute, so the chart type can be a variable rather than a fixed tag. That is useful for a page where the user picks the visualisation.
Global options and the Vue 2 split
Options that apply to every chart in an application are set globally, through a static options object on Chartkick itself:
Chartkick.options = {
colors: ["#b00", "#666"]
}The example uses the colour palette, which is the option most worth setting globally, since a consistent palette across a dashboard is the difference between a set of charts that read as one system and a set that read as separate widgets. The same object carries the other shared options, so the global defaults and the per-chart props use the same vocabulary.
Per series, a small set of options can be attached to an individual series object: name, data and color are generic, while dataset, points and curve are marked as Chart.js only. The name is what appears in the legend, and the color overrides the palette for that series, which is the mechanism for making one series stand out in a multi-series chart without redefining the whole palette.
The version situation is the other thing to settle. The latest version works with Vue 3, and for Vue 2 the README directs you to version 0.6.1 and a separate readme on the vue2-docs branch. That is a hard split rather than a compatibility shim, so a project still on Vue 2 is working with a much older API surface, and the peer dependency confirms the current line requires Vue 3.0 or above.
The project is not archived and the last push was on 2026-06-29, with no GitHub releases, so the npm version and the repository are the two places to watch. The licence is MIT with the terms in a LICENSE.txt file, and the author is Andrew Kane.
Editorial conclusion
vue-chartkick is worth taking for a Vue 3 dashboard or admin panel, because it removes the boilerplate of instantiating a chart library and keeps it in sync with the component tree, which is the part people get wrong when they wire a chart library up by hand. It is the wrong tool if you need chart types outside the list, if you want to own the rendering lifecycle completely, or if you are on Vue 2, since that line lives on version 0.6.1 with its own readme and branch. Before you adopt it, verify three things yourself: that the backing library you want is one of the three supported, since the geo chart and the timeline are Google Charts only and the download option is Chart.js only, that your data prop is a reactive property rather than an inline literal, because the README warns that literals cause unnecessary re-renders, and that the chartkick version you resolve meets the stated minimum of 3.2.0.
Frequently asked questions
How do I create a chart in Vue with vue-chartkick?
Install vue-chartkick and a backing library such as chart.js, then register the wrapper with app.use(VueChartkick). A chart is then a template tag such as <line-chart :data="{'2026-01-01': 11}"></line-chart> with the data passed as a prop.
Which charting libraries does vue-chartkick support?
Chart.js, Google Charts and Highcharts. The import of chartkick/chart.js selects Chart.js, and the import line is what changes when you pick a different one. Some options are library specific, with the geo chart and timeline marked Google Charts only and the download option marked Chart.js only.
Can a vue-chartkick chart load data from a URL?
Yes. The data attribute accepts a URL such as data="/stocks", which lets each chart have its own endpoint so the page renders without waiting for the data. There is also a refresh option that reloads from a remote source every n seconds.
Why does the README warn about inline object literals in props?
An object literal written inline in a template is a new value on every render, so the chart component sees a changed prop and re-renders unnecessarily. The README recommends passing a data property instead, and links to a Vue issue discussion on the pattern.
Does vue-chartkick work with Vue 2?
The latest version works with Vue 3 and the peer dependency requires Vue 3.0 or above. For Vue 2 the README directs you to version 0.6.1 with a separate readme on the vue2-docs branch.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ankane-vue-chartkick)Was this useful?