Release 2026-10-02
- #10432: Generate lazy AsyncAPI channel, operation, message, and schema chunks. Group shared dependencies to reduce requests while preserving direct model loading, recursive references, navigation, servers, and authentication.
- #10458: Stop walking every path through shared schemas when collecting a parameter's declared example values. A shared schema found to declare no values is now skipped on the other paths that reach it, so a request whose parameter points into a deep graph of shared schemas no longer takes seconds to minutes to render.
- #10372: fix: improve keyboard and screen reader access to code blocks and multiselect comboboxes
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
operation.codeSample) so screen readers announce it when it receives focus - The code block copy button now has a stable accessible name ("Copy Shell code") in every state, including while its visible label is hidden
- In multiselect comboboxes such as the auth scheme picker, Space toggles the active option while the search query is empty instead of hiding the whole list
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
-
#10372: fix: improve keyboard and screen reader access to code blocks and multiselect comboboxes
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
operation.codeSample) so screen readers announce it when it receives focus - The code block copy button now has a stable accessible name ("Copy Shell code") in every state, including while its visible label is hidden
- In multiselect comboboxes such as the auth scheme picker, Space toggles the active option while the search query is empty instead of hiding the whole list
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
-
#10437: Stop a discriminator
oneOfvariant that composes its base withallOffrom rendering a second selector, its fields twice, or a repeated variant description. -
#10439: Fix missing chunks after a release when a cached ESM entry point is loaded from an unversioned npm CDN URL. The generated loader selects its own exact release using a relative package URL, preserving the CDN hostname and path prefix. This supports jsDelivr, UNPKG, and other hosts with versioned npm package paths while keeping latest as the default. Custom self-hosted paths continue loading the bundle next to the entry point.
- #10372: fix: improve keyboard and screen reader access to code blocks and multiselect comboboxes
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
operation.codeSample) so screen readers announce it when it receives focus - The code block copy button now has a stable accessible name ("Copy Shell code") in every state, including while its visible label is hidden
- In multiselect comboboxes such as the auth scheme picker, Space toggles the active option while the search query is empty instead of hiding the whole list
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
- #10459: Share one lowlight instance per language registry between
syntaxHighlightandhtmlFromMarkdowninstead of registering and compiling every grammar for each code block, and replace it after a grammar fails to compile so later blocks that embed that grammar keep their text
- #10372: fix: improve keyboard and screen reader access to code blocks and multiselect comboboxes
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
operation.codeSample) so screen readers announce it when it receives focus - The code block copy button now has a stable accessible name ("Copy Shell code") in every state, including while its visible label is hidden
- In multiselect comboboxes such as the auth scheme picker, Space toggles the active option while the search query is empty instead of hiding the whole list
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
-
#10411: Import API descriptions from reference page URLs, including Hono pages, and retain discovered document URLs for watch mode.
Ignore JSON-LD website metadata during URL discovery and preserve link and escaped-JSON fallbacks for URLs with unsupported JavaScript escapes.
- #10412: Update the shared Undici dependency to 7.29.1 to fix security advisories while preserving Node 22 compatibility, and update Scalar App’s separate Undici pin to 8.11.2.
- #10457: Render a selected operation, model, tag or webhook in time proportional to the selection instead of the whole document.
- #10372: fix: improve keyboard and screen reader access to code blocks and multiselect comboboxes
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
operation.codeSample) so screen readers announce it when it receives focus - The code block copy button now has a stable accessible name ("Copy Shell code") in every state, including while its visible label is hidden
- In multiselect comboboxes such as the auth scheme picker, Space toggles the active option while the search query is empty instead of hiding the whole list
- The code block scroller is exposed as a named group ("Code sample: Shell cURL" in the API Reference, localizable via
- #10417: Reduce union scoring overhead for literals, arrays, records, and missing optional values while preserving branch selection.
-
#10412: Update the shared Undici dependency to 7.29.1 to fix security advisories while preserving Node 22 compatibility, and update Scalar App’s separate Undici pin to 8.11.2.
-
#10411: Import API descriptions from reference page URLs, including Hono pages, and retain discovered document URLs for watch mode.
Ignore JSON-LD website metadata during URL discovery and preserve link and escaped-JSON fallbacks for URLs with unsupported JavaScript escapes.
- @scalar/api-reference@1.72.4
- @scalar/api-reference@1.72.4
- @scalar/api-reference@1.72.4
- @scalar/api-reference@1.72.4
- @scalar/api-reference@1.72.4
- @scalar/api-reference@1.72.4
- @scalar/api-reference@1.72.4
💎 Version 7.8.0
Two default changes to know about before upgrading, both about data labels.
Data labels that land on each other are now nudged apart. A chart whose labels already clear each other is untouched, but anywhere two of them currently overlap, they will move. Turn it off with:
dataLabels: { avoidOverlap: false }
This matters most on a chart with two y-axes, where the axes are scaled independently and a collision is therefore not a question of how close the values are: a column at 59.5K and a line at 68K can land on the same pixel row while 51K and 51.3K sit well apart. Labels separate along the value axis, so a horizontal bar's move sideways rather than across its rows. A pair that cannot be separated is left overlapping rather than quietly dropped, since removing a value is worse than the overlap; pass { hide: true } if you would rather lose one. Rotated labels and the radial types keep their own placement.
It is on by default because a label sitting on another is never what the chart meant to say, and the pass does nothing to a chart that does not need it. Across the 320 demo charts that predate it, not one renders differently.
A waterfall's data labels have lost their pale chip. The ink follows chart.foreColor instead, which reads over a rising, falling or total bar in either theme, and on the small steps whose label sits outside the bar. The chip is still there if you want it:
dataLabels: { background: { enabled: true } }
It is worth more than it was, incidentally. The chip used to inherit the range column's white ink, and a chip takes its fill from its text, so on a light theme it was white on white.
Two performance fixes ship without a section of their own. A CPU profile of a hover sweep over a 700-series chart put 38% of all hover time inside native querySelector and another 10% in forced layout, from lookups repeated per marker rather than per gesture; both are now done once per gesture. Separately, data label backgrounds are measured in one pass instead of relaying the SVG out once per label, which on thousands of labels is the difference between seconds and milliseconds.
dataLabels.style.colors entries may be functions. That has always been true at runtime and the documentation has always said so; the TypeScript declaration said string[] and now agrees.
| gzip | |
|---|---|
| 7.7.0 default bundle | 272,129 B |
| 7.8.0 default bundle | 273,832 B |
Both are dist/apexcharts.min.js gzipped at the default level, which is the figure npm run build prints.
Upgrading is npm install apexcharts@7.8.0.
A waterfall printed every step on a pale rounded chip. On a dense bridge that is a second rectangle per bar competing with the bar it names, and the type is usually a dense bridge.
The chip was not decoration, though, so removing it alone would reopen what it was added to fix. Small steps are normal in a waterfall, and a label wider or taller than its bar is placed OUTSIDE it; the range-column defaults the type inherits draw labels in white, so those labels became white text on the chart background and the smallest steps of a P&L bridge simply vanished.
So the ink moves instead of hiding behind a chip. dataLabels.style.colors now carries a function that resolves to chart.foreColor, which is dark on a light theme and light on a dark one, and reads over an increase, decrease or total bar either way. Verified in both modes: #373d3f on light, #f6f7f8 on dark, and no rect in the DOM.
An entry in that array has always been allowed to be a function - the resolution in plotDataLabelsText calls one if it finds one - but the declaration said string[]. It now says what the implementation does.
Set dataLabels.background.enabled to get the chip back.
Reported from the field: a dual-axis chart printed "$59.53K$59.53K" where a column series and a line series coincided, and a waterfall ran its currency labels together between adjacent quarters.
dataLabelsCorrection looks like it already handles this, but it cannot. It is keyed on dataLabelsRects[i], one series, and it runs WHILE that series is plotting, so the labels it would collide with do not exist yet. It also measures the raw text rather than the background pill, which is why a few pixels of pill overlap got through even within one series.
dataLabels.avoidOverlap is a pass over every label once they are all drawn, before the pills are cut. It is on by default: a label sitting on another is never what the chart meant to say, and the pass is a no-op on a chart whose labels already clear each other.
The thing worth knowing for a multi-axis chart is that collisions are NOT a function of how close the values are. The two axes scale independently, so only pixels decide. Sweeping the line series from -30% to +30% of the columns in 1% steps: collides -27%..0%, clean +1%..+11%, collides again +12%..+17%, clean after that. 34 of 61 configurations collided, 88 pairs in total, 0 after.
Design, each point of which was a defect found by auditing 25 configurations across types, orientations and label positions:
- Separation runs along the VALUE axis, not a fixed vertical. On a horizontal bar the vertical axis is the CATEGORY axis, so nudging there walks a label into the next row; those transpose and move along x instead. Vertical-only separation cost 8 of 18 labels on a crowded horizontal bar.
- Dropping a label is opt-in (
{hide: true}). A default-on pass that silently deletes a value is worse than the overlap it set out to fix, so an unseparable pair is left exactly as it renders today. - Boxes are measured with
getBoundingClientRect, notgetBBox. getBBox is taken before the element's own transform, so a label underplotOptions.bar.dataLabels.orientation: 'vertical'measures 29x14 while it occupies 14x29. getBBox remains the SSR fallback, where the DOM shim estimates text extents but has no client rect. - A rotated label is an obstacle, never a mover: its
yattribute runs along its own rotated axis, so writing to it would slide it sideways. - Radial types opt out. Radar lost 3 of 12 labels to a vertical nudge before the skip; pie and friends run their own de-overlap already.
- Pairwise relaxation, not column packing, which would chain a dense row into one tall stack through its neighbours. Each pair splits the push and each label is capped at
maxShiftfrom its own mark. - Bounds are the plot with no slack, since past that edge a label is clipped. A label that legitimately starts outside, the one above a bar that reaches the top of the grid, keeps its place: the clamp restricts movement and never forces it.
Geometry lives in its own helper over plain numbers, so it is tested without a DOM; the DOM half needs real text metrics and is tested in the browser. Both suites assert the collision is still there with the option off, so neither can pass vacuously.
Two samples carry currency formatters and the reported shapes: a 15-step waterfall bridge and the dual-axis combo.
Both ajax demos fetched http://my-json-server.typicode.com/apexcharts/ apexcharts.js/yearly, a third-party fake-API. That service is gone: it answers 530 with Cloudflare error 1016, an origin DNS failure, over http and https alike. So the demos have been showing "Loading..." forever on the site, and Test Reproducibility has failed on misc/axios on every push since 2026-10-01, which is why main has been red for seven runs. The e2e runner fails a sample on console errors, and a dead fetch logs one.
my-json-server was only ever serving db.json out of this repository, and that file is still here, so the fix is to read it from a CDN that serves this repository directly. The payload is the whole object rather than one key, so both demos now take .yearly off it.
The data is identical, which the snapshots confirm: both samples pass against the references captured while the old endpoint was alive, with no baseline update. The full suite is 322 passing, 0 failing - the first clean e2e run in a while, since these two were the standing failures.
These demos still pull jquery and axios themselves from cdnjs, so they are not free of the network, but they no longer depend on a service nobody here controls.
v16.4.0-canary.57
- Resolve React dependency warnings from the target app: #99536
- Move upgrade workflows out of public docs: #99546
- Use Agent terminology throughout upgrades: #99545
- Turbopack: Commit updated generated-native file: #99561
- test: enable Relay multi-project deployment coverage: #99403
- test: migrate independent App Router deploy exclusions to force gates: #99431
- test: migrate mode-specific deploy exclusions to force gates: #98160
Huge thanks to @devjiwonchoi, @bgw, @jamiboym, and @gnoff for helping!
v16.4.0-canary.56
- Measure AI upgrade nudges, handoffs, and completion: #99465
- turbo-persistence: 32 bit fingerprints for the used keys AMQFs: #99333
- Remove suspend during operations: #99383
- test: migrate runtime deploy exclusions to force gates: #98159
- test: migrate asset deploy exclusions to force gates: #98158
- test: migrate Pages Router deploy exclusions to force gates: #98157
- fix: stale usages of unstable_ensureStatic: #99540
- Add unstable parameter matching APIs: #97393
- docs: point next package security disclosure to HackerOne: #99459
- docs: add ensureStatic reference and validation guidance: #99355
- Enable Turbopack export name mangling by default for builds: #99362
- Allow skipping React and ESLint upgrades: #99468
- Prefer the declared package manager during upgrades: #99471
- Use Next.js conventions in bundle analyzer UI: #98780
- Pass App Page HMR state through a dev render context: #99487
- Remove request forwarding from App Router error reporting: #99488
- docs: self hosting immutable static assets: #97008
- test: enable deployment fixtures with Corepack and portable tarballs: #99192
Huge thanks to @devjiwonchoi, @lukesandberg, @jimmyhmiller, @gnoff, @lubieowoce, @swarnava, @aurorascharff, @sokra, @wbinnssmith, @mischnic, and @jamiboym for helping!
static-middleware v1.0.0
- First stable release.
- Bumped
@remix-run/*dependencies:
test v1.0.0
- First stable release.
- Bumped
@remix-run/*dependencies:
ui v0.12.1
- Bumped
@remix-run/*dependencies: