A charting dependency can change a dashboard without changing a single API endpoint. That is the uncomfortable part of an ApexCharts 6.4 upgrade.
The release was published on 2026-07-20, and it changes the rules that turn a heatmap data point into pixels, interaction, and labels. It also introduces an opt-in Canvas renderer with its own import requirement and fallback behavior. Those are dashboard contracts: visible agreements between your data, your configuration, and the people who use the screen. The v6.4.0 release notes are the source for those changes.
Calling this a package bump invites the wrong workflow: update the lockfile, click through a happy-path page, and merge. A dashboard has too many quiet dependencies for that. A support manager may rely on a tooltip staying near the pointer. An operations user may rely on zoom to inspect a dense time range. A weekly activity heatmap may rely on every row label remaining visible. None of those expectations appears in a TypeScript import statement.
This post treats 6.4 as a controlled migration for a Laravel/Vue SaaS dashboard: inspect the current contract, choose the new behavior deliberately, and prove both the preferred path and the rollback path. The same approach applies outside Laravel and Vue. If you are building or maintaining the stack described in Laravel + Vue SaaS, use the chart as an owned interface, not as decorative output from a dependency.

The release changes a dashboard’s observable contract
A contract is broader than a function signature. For a heatmap, it includes where a cell sits, what a hover reveals, whether a user can zoom, which labels survive density controls, and whether the renderer produces the expected output. Those behaviors are visible. Once users learn them, they become part of the product.
ApexCharts 6.4 contains three categories of change that deserve separate review:
| Area | What must be treated as a contract |
|---|---|
| Heatmap geometry | Numeric and datetime cells can follow their real x values rather than an even category grid. |
| Rendering path | Canvas is optional and requires an explicit feature import; unsupported fills use SVG instead. |
| Default behavior | Tooltip placement, zoom, and y-axis label density changed for heatmaps. |
The release states that irregular numeric and datetime heatmaps position cells at their actual x values. It also documents the Canvas import, SVG fallback for unsupported fills, and the changed heatmap defaults. Read those claims in the v6.4.0 release notes, then test them against the charts you ship.
This is why release notes should become test inputs. Do not translate “irregular data now uses real x positions” into “the chart is more correct” and move on. Translate it into a fixture with irregular values, a named expected behavior, and a screenshot or DOM-level assertion that someone can review during a future upgrade.
The same discipline matters when the release includes performance results. Any benchmark in the release belongs to the upstream harness that produced it. It is evidence about that harness, not a promise about your browser mix, dataset shape, page composition, or user-perceived dashboard speed. The release itself is the only appropriate source for those figures; do not turn them into a product SLA. ApexCharts v6.4.0 release notes
A useful migration ticket therefore has a different title from “upgrade ApexCharts.” Name the affected screens and their behavior: “Preserve incident-heatmap tooltip and zoom behavior while adopting real-x positioning.” That wording forces a conversation about the user-facing contract before implementation details take over.
Real x positions change the meaning of an irregular heatmap
Many dashboards receive telemetry or business events at uneven intervals. A numeric x value may be a batch number, queue depth, or elapsed minute. A datetime x value may represent an event that occurred after a gap. When a renderer treats those entries as evenly spaced categories, the eye reads equal distance where the underlying values are not equally spaced.
ApexCharts 6.4 changes this for irregular numeric and datetime heatmaps: cells are positioned at their real x values. That is an intentional release behavior, documented in the v6.4.0 notes. If your heatmap already uses evenly spaced categories, the visual result may remain familiar. If it contains gaps, the plot can visibly redistribute itself after the upgrade.
Use an explicit fixture that makes gaps impossible to miss. This is a plain ApexCharts configuration that uses datetime x values with an intentional two-hour break:
1import ApexCharts from "apexcharts";
2
3const options: ApexCharts.ApexOptions = {
4 chart: {
5 type: "heatmap",
6 height: 280,
7 },
8 series: [
9 {
10 name: "API errors",
11 data: [
12 { x: new Date("2026-07-20T08:00:00Z").getTime(), y: 1 },
13 { x: new Date("2026-07-20T08:05:00Z").getTime(), y: 4 },
14 { x: new Date("2026-07-20T10:10:00Z").getTime(), y: 2 },
15 ],
16 },
17 ],
18 xaxis: {
19 type: "datetime",
20 },
21};
22
23const chart = new ApexCharts(document.querySelector("#error-heatmap"), options);
24chart.render();
Keep this fixture small. A chart with thousands of points is useful for load testing, but it is poor at explaining a geometry change in code review. Three values with an obvious gap answer the important question: does the horizontal distance represent the values we supplied?
There is a product decision hidden inside that question. Real positions may expose downtime, missing collection windows, sparse activity, or gaps caused by filters. That can be the correct visual story. It can also surprise a team whose existing dashboard used a heatmap as a compact categorical matrix. Do not “fix” the new spacing with CSS until you have agreed which story the chart should tell.
Capture a before-and-after image for each affected chart family, not just the first dashboard page. The same wrapper may feed different x-axis types in billing, monitoring, fulfillment, and admin reporting. Search your codebase for type: "heatmap", then classify each chart by x data: categories, numbers, or dates. This belongs in the upgrade checklist alongside version changes.

Canvas is an explicit renderer choice, not a silent acceleration switch
The 6.4 release adds a Canvas heatmap renderer, but it does not turn on merely because the package version changes. The documented requirement is an explicit side-effect import:
1import ApexCharts from "apexcharts";
2import "apexcharts/features/renderer-canvas";
That import is required for the Canvas heatmap renderer according to the v6.4.0 release. Put it in a deliberate client-side entry point. Do not scatter it through leaf components, where route-level code splitting can make the renderer’s availability hard to reason about.
The release also says Canvas falls back to SVG for unsupported fills. That matters because “the chart rendered” does not prove it used Canvas. A fallback can be the intended compatibility behavior, but your tests need to distinguish expected output from an assumption that every heatmap has the same renderer. ApexCharts v6.4.0
For a Vue application, keep registration and client-only rendering separate. The following component setup is syntactically usable in a client-rendered Vue app. It shows the shape of the integration, not a claim that any wrapper supports ApexCharts 6.4:
1// src/charting/apexcharts-client.ts
2import ApexCharts from "apexcharts";
3import "apexcharts/features/renderer-canvas";
4
5export function createHeatmap(
6 element: Element,
7 options: ApexCharts.ApexOptions,
8): ApexCharts {
9 const chart = new ApexCharts(element, options);
10 void chart.render();
11 return chart;
12}
1<script setup lang="ts">
2import { onBeforeUnmount, onMounted, ref } from "vue";
3import type ApexCharts from "apexcharts";
4import { createHeatmap } from "@/charting/apexcharts-client";
5
6const root = ref<HTMLElement | null>(null);
7let chart: ApexCharts | undefined;
8
9onMounted(() => {
10 if (!root.value) return;
11
12 chart = createHeatmap(root.value, {
13 chart: { type: "heatmap", height: 260 },
14 series: [{ name: "Jobs", data: [{ x: 1, y: 8 }, { x: 5, y: 3 }] }],
15 });
16});
17
18onBeforeUnmount(() => {
19 chart?.destroy();
20});
21</script>
22
23<template>
24 <div ref="root" />
25</template>
Whether you use direct ApexCharts or a wrapper, add an explicit renderer test matrix: supported fill, unsupported fill, a realistic sparse dataset, and the exact browser targets your application supports. Do not write a test that asserts implementation details you cannot observe. A visual regression image plus a successful interaction test is stronger than a test that merely checks that a module was imported.
The new defaults can break muscle memory without throwing an error
ApexCharts 6.4 changes three heatmap defaults: the tooltip appears above the cell, zoom is disabled, and y-axis labels are thinned. All three are documented in the release notes. None necessarily produces an exception. That is what makes them migration work.
Tooltip placement affects the hand and eye. A user who hovers across a row expects the value to appear in a stable place relative to the cell or pointer. Disabling zoom changes a familiar escape hatch for reading dense screens. Label thinning can remove context from a chart whose row names are the whole point. A shipping dashboard, for example, may have a short visible chart but many meaningful lanes. A chart that hides labels may remain technically legible while becoming operationally weaker.
The release provides explicit ways to restore the earlier behavior: set tooltip.followCursor to true, set chart.zoom.enabled to true, and provide a custom yaxis.labels.formatter. Use those settings only after checking why the new defaults exist and whether the old interaction still fits the current chart. ApexCharts v6.4.0
Here is a concrete preservation configuration:
1const options: ApexCharts.ApexOptions = {
2 chart: {
3 type: "heatmap",
4 zoom: {
5 enabled: true,
6 },
7 },
8 tooltip: {
9 followCursor: true,
10 },
11 yaxis: {
12 labels: {
13 formatter: (value: string) => value,
14 },
15 },
16 series: [
17 { name: "Payments", data: [{ x: "Mon", y: 12 }, { x: "Tue", y: 7 }] },
18 ],
19};
Treat that snippet as a compatibility choice, not ceremonial configuration. Add an interaction test that drags or uses the zoom control according to your application flow. Add a visual test at the narrowest supported dashboard width to prove the y labels are still useful. Hover a cell and inspect the tooltip position. When your team later decides to accept the 6.4 defaults, remove these settings with the same test coverage instead of letting them linger as cargo-cult options.

Vue wrapper status is a separate compatibility question
A core-library release and a wrapper release are separate facts. The npm page for vue3-apexcharts lists version 1.11.1. That version number does not establish compatibility with ApexCharts 6.4, and it does not establish Nuxt SSR compatibility. The official sources named here do not provide that guarantee, so do not claim one in an upgrade plan.
This boundary changes the order of work. First, test the direct ApexCharts package and the charts you own. Then test the wrapper where it is actually used. Finally, test the server-rendered build and hydration path if your app uses Nuxt or another SSR setup. A page that works after client navigation may still fail in a server render or hydrate into a different DOM shape.
A practical repository check can surface where the wrapper enters the app:
1// scripts/find-apexcharts-usage.mjs
2import { glob } from "glob";
3import { readFile } from "node:fs/promises";
4
5const files = await glob(["src/**/*.{ts,tsx,vue}", "pages/**/*.vue", "components/**/*.vue"]);
6const pattern = /vue3-apexcharts|apexcharts\/features\/renderer-canvas|type:\s*["']heatmap["']/;
7
8for (const file of files) {
9 const source = await readFile(file, "utf8");
10 if (pattern.test(source)) console.log(file);
11}
Run a tool like this before changing imports. It tells you whether you have direct usage, wrapper usage, or both. Then build a small test page for each path. For SSR, render the route in the same mode your deployment uses, then load it in a browser and check hydration, resize behavior, hover, and teardown after navigation.
Do not solve uncertainty by upgrading the wrapper and core together, then declaring victory after one local page. Keep the dependency boundary visible in the pull request. State what the sources confirm: ApexCharts 6.4 behavior comes from its release, while the npm listing shows vue3-apexcharts 1.11.1. Everything else requires your own compatibility test.

What you should do Monday morning
- Create a branch that changes only the ApexCharts dependency and its lockfile. Record the current package version and the rollback command in the pull request before testing begins.
- Search for every heatmap and classify its x data as category, numeric, or datetime. Add one irregular numeric or datetime fixture wherever real spacing matters, because 6.4 places those cells at real x values. Release source
- Take baseline screenshots at desktop and narrow dashboard widths. Include a hovered cell, the complete y-axis label set, and any zoomed state users rely on.
- Decide chart by chart whether to adopt the new defaults or preserve the old behavior. If preservation is required, add
tooltip.followCursor: true,chart.zoom.enabled: true, and ayaxis.labels.formatter, then test each behavior. Those restoration options are documented in the v6.4.0 release. - If you want Canvas heatmaps, add
import "apexcharts/features/renderer-canvas";in a controlled client entry point. Test a fill you expect to render with Canvas and a fill that may use the documented SVG fallback. Release source - Test direct ApexCharts and
vue3-apexchartsseparately. The npm listing identifies the wrapper as 1.11.1; it does not certify 6.4 or Nuxt SSR compatibility. npm source - Run the real production build, open the affected routes, navigate away and back, resize, hover, zoom where applicable, and compare screenshots. Keep the old dependency version ready until those checks pass.
- Write the decisions into the maintenance record. Link the chart fixtures, screenshots, chosen renderer path, accepted default changes, and rollback point from your developer tools notes so the next maintainer does not have to reconstruct the reasoning from a lockfile.
The goal is not to preserve every old pixel. The goal is to make intentional changes, expose them in review, and keep evidence for the next package update. That is ordinary engineering work, but dashboards punish teams that skip it.
Further reading
- Start with the site’s orientation page if you are new to the maintenance notes and frontend writing on zemna.net.
