Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/portable-compatibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@tanstack/charts': patch
---

Restore the published `/portable` entry as a compatibility alias of
`/universal`. The browser-oriented root and preferred `/universal` entry remain
unchanged.
45 changes: 30 additions & 15 deletions API-FRICTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3687,14 +3687,21 @@ Each entry records:
- Friction: Changesets advanced manifests, package changelogs, and the lockfile
but left the root README, canonical docs, comparison evidence links, and
marketing material on 0.0.1. Merging the generated pull request would have
published a newer package line beside stale install and status claims.
published a newer package line beside stale install and status claims. The
synchronizer also treats every current-version literal in an allowlisted
source as mutable, so a second explanatory mention made the replacement
boundary ambiguous and failed CI.
- Decision: derive the previous release from the generated root changelog,
advance an explicit allowlist of release-facing sources, then run the
repository's canonical docs sync before formatting the version pull request.
Historical changelog and friction evidence remain immutable.
Keep each allowlisted source's configured number of replaceable
current-version references stable; compatibility guidance should not add an
ambiguous extra reference. Historical changelog and friction evidence remain
immutable.
- Verification: focused tests cover version-heading discovery, complete
replacement, idempotency, and missing-version rejection. Generated package
docs remain outputs of `pnpm docs:sync`, never hand-edited sources.
replacement, idempotency, ambiguous-reference rejection, and missing-version
rejection. Generated package docs remain outputs of `pnpm docs:sync`, never
hand-edited sources.

### F-154 — Root barrels crossed the browser host boundary

Expand All @@ -3706,26 +3713,34 @@ Each entry records:
platform-neutral, but the root value barrel made bundlers traverse DOM hosts,
adapters, reconciliation, and SVG surfaces. Its type graph also declared
`Element`, `HTMLElement`, and `SVGSVGElement`, so a non-DOM consumer could
not select the universal contracts as one supported entry.
not select the universal contracts as one supported entry. While the naming
change was in flight, 0.1.0 published the initial `/portable` entry, making
its removal a breaking change for published consumers. The generated 0.2.0
release merged before the compatibility follow-up and published that removal.
The subsequent 0.3.0 and 0.3.1 releases also shipped before the follow-up
could land, so the restoration must remain a focused patch after the latest
release boundary.
- Decision: preserve the existing browser-oriented root API and add
`@tanstack/charts/universal` for common authoring/runtime values plus
`@tanstack/charts/types` for universal contracts. The name describes the
supported cross-runtime surface while the browser-first root remains the
normal web entry. DOM surface, renderer, host, and render-context types now
live behind an internal module while retaining their existing root
re-exports. Definition inputs retain DOM-free extension token contracts while
the generic tooltip and portal token interfaces are exported for host-adapter
authors. Typed DOM tooltip and portal lifecycles remain in the DOM module. Do
not conditionally change the root until a native host can test one coherent
platform contract.
- Verification: root typechecking and 61 focused core tests pass. The packed
package gate resolves both new entries from `dist`, compiles their
normal web entry. Restore `/portable` as a compatibility alias for the
published 0.1.0 surface in the next patch after 0.3.1. DOM surface, renderer,
host, and render-context types now live behind an internal module while retaining
their existing root re-exports. Definition inputs retain DOM-free extension
token contracts while the generic tooltip and portal token interfaces are
exported for host-adapter authors. Typed DOM tooltip and portal lifecycles
remain in the DOM module. Do not conditionally change the root until a native
host can test one coherent platform contract.
- Verification: root typechecking and focused core tests pass. An export test
verifies portable/universal runtime parity. The packed package gate resolves
`/portable`, `/universal`, and `/types` from `dist` and compiles their
declarations, including tooltip definition inputs and direct generic-token
imports, with Web Worker rather than DOM globals. Type regressions reject
swapping tooltip and portal tokens.
The packed bundle proof excludes the root, adapters, Canvas, DOM host/text,
browser export, reconciliation, renderer, and SVG surface modules. That full
universal barrel measures 53.95 kB minified and 16.60 kB gzip; granular
universal barrel measures 84.30 kB minified and 26.55 kB gzip; granular
subpaths remain the bundle-sensitive option.

### F-155 — Optional tooltip code burdened every chart consumer
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## Unreleased

### Fixed

- Restored `@tanstack/charts/portable` as a compatibility alias of
`@tanstack/charts/universal`. The browser-oriented root and preferred
`/universal` entry remain unchanged.

## 0.3.1

### @tanstack/charts
Expand Down
6 changes: 3 additions & 3 deletions benchmarks/comparison/bundle-baseline.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"schemaVersion": 3,
"generatedAt": "2026-07-31T21:48:07.702Z",
"generatedAt": "2026-07-31T22:21:14.951Z",
"packageVersions": {
"tanstack": "0.3.0",
"tanstack": "0.3.1",
"chartjs": "4.5.1",
"echarts": "6.1.0",
"recharts": "3.10.1",
Expand All @@ -11,7 +11,7 @@
"sources": {
"tanstack": {
"kind": "workspace",
"revision": "c422a2ce45799d4edd63fdbde7ecb31daa3dae31"
"revision": "43ae5f37661189cfeb6431e588d7610dd6542ff1"
},
"chartjs": {
"kind": "package",
Expand Down
9 changes: 5 additions & 4 deletions docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ description: Compare current TanStack Charts workspace source with pinned Chart.
---

TanStack Charts `0.3.1` is a pre-alpha release. Its results on this page measure
the exact workspace source included in this release and pinned competitor
the exact current workspace revision recorded below and pinned competitor
packages. This comparison records architectural differences and reproducible
evidence without turning untested behavior into a checkmark.

## Tested versions

| Library | Package | Measured source |
| -------------------------------------------------------------------------------------- | -------------------- | ------------------- |
| [TanStack Charts](./overview.md) | `@tanstack/charts` | workspace `c422a2c` |
| [TanStack Charts](./overview.md) | `@tanstack/charts` | workspace `43ae5f3` |
| [Chart.js](https://www.chartjs.org/docs/latest/) | `chart.js` | npm `4.5.1` |
| [Apache ECharts](https://echarts.apache.org/handbook/en/best-practices/canvas-vs-svg/) | `echarts` | npm `6.1.0` |
| [Recharts](https://recharts.github.io/en-US/) | `recharts` | npm `3.10.1` |
| [Observable Plot](https://observablehq.com/plot/features/plots) | `@observablehq/plot` | npm `0.6.17` |

The competitor versions are exact package pins, not latest versions inferred
at page render time. The measured TanStack workspace revision is `c422a2c`.
at page render time. The measured TanStack workspace revision is `43ae5f3`.

## Capability matrix

Expand Down Expand Up @@ -111,7 +111,8 @@ Canvas composition while keeping D3 and state ownership explicit.
## Evidence and reproduction

- [Standard comparison protocol](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/README.md)
- [Tracked bundle baseline](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/bundle-baseline.json)
- [Tracked current bundle baseline](https://github.com/TanStack/charts/blob/main/benchmarks/comparison/bundle-baseline.json)
- [Tagged release bundle baseline](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/bundle-baseline.json)
- [Stress protocol](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/stress/README.md)
- [Catalog conformance protocol](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/conformance/README.md)

Expand Down
7 changes: 5 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,11 @@ import {
import type { ChartDefinition } from '@tanstack/charts/types'
```

The root remains the browser-oriented compatibility entry. Subpaths expose the
same contracts behind explicit capability boundaries.
The root remains the primary browser-oriented entry. Subpaths expose the same
contracts behind explicit capability boundaries.

`@tanstack/charts/portable` remains a compatibility alias for existing
consumers. New environment-neutral code should use `/universal`.

Optional capabilities have explicit entries:

Expand Down
1 change: 1 addition & 0 deletions docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ capabilities and individual marks independently tree-shakeable.
| `@tanstack/charts/link` | `link` |
| `@tanstack/charts/mark/scale-values` | `createMarkWithScaleValues` |
| `@tanstack/charts/polar` | `polar`, radial arc/line/area/dot marks, and radial/angle guides |
| `@tanstack/charts/portable` | Compatibility alias for `@tanstack/charts/universal` |
| `@tanstack/charts/universal` | Common root authoring, runtime, scene, and static SVG values without browser hosts or adapters |
| `@tanstack/charts/reconcile` | `reconcileChartSvg` |
| `@tanstack/charts/rect` | `rect`, `cell` |
Expand Down
9 changes: 5 additions & 4 deletions packages/charts-core/docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ description: Compare current TanStack Charts workspace source with pinned Chart.
---

TanStack Charts `0.3.1` is a pre-alpha release. Its results on this page measure
the exact workspace source included in this release and pinned competitor
the exact current workspace revision recorded below and pinned competitor
packages. This comparison records architectural differences and reproducible
evidence without turning untested behavior into a checkmark.

## Tested versions

| Library | Package | Measured source |
| -------------------------------------------------------------------------------------- | -------------------- | ------------------- |
| [TanStack Charts](./overview.md) | `@tanstack/charts` | workspace `c422a2c` |
| [TanStack Charts](./overview.md) | `@tanstack/charts` | workspace `43ae5f3` |
| [Chart.js](https://www.chartjs.org/docs/latest/) | `chart.js` | npm `4.5.1` |
| [Apache ECharts](https://echarts.apache.org/handbook/en/best-practices/canvas-vs-svg/) | `echarts` | npm `6.1.0` |
| [Recharts](https://recharts.github.io/en-US/) | `recharts` | npm `3.10.1` |
| [Observable Plot](https://observablehq.com/plot/features/plots) | `@observablehq/plot` | npm `0.6.17` |

The competitor versions are exact package pins, not latest versions inferred
at page render time. The measured TanStack workspace revision is `c422a2c`.
at page render time. The measured TanStack workspace revision is `43ae5f3`.

## Capability matrix

Expand Down Expand Up @@ -111,7 +111,8 @@ Canvas composition while keeping D3 and state ownership explicit.
## Evidence and reproduction

- [Standard comparison protocol](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/README.md)
- [Tracked bundle baseline](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/bundle-baseline.json)
- [Tracked current bundle baseline](https://github.com/TanStack/charts/blob/main/benchmarks/comparison/bundle-baseline.json)
- [Tagged release bundle baseline](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/bundle-baseline.json)
- [Stress protocol](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/comparison/stress/README.md)
- [Catalog conformance protocol](https://github.com/TanStack/charts/blob/v0.3.1/benchmarks/conformance/README.md)

Expand Down
7 changes: 5 additions & 2 deletions packages/charts-core/docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,11 @@ import {
import type { ChartDefinition } from '@tanstack/charts/types'
```

The root remains the browser-oriented compatibility entry. Subpaths expose the
same contracts behind explicit capability boundaries.
The root remains the primary browser-oriented entry. Subpaths expose the same
contracts behind explicit capability boundaries.

`@tanstack/charts/portable` remains a compatibility alias for existing
consumers. New environment-neutral code should use `/universal`.

Optional capabilities have explicit entries:

Expand Down
1 change: 1 addition & 0 deletions packages/charts-core/docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ capabilities and individual marks independently tree-shakeable.
| `@tanstack/charts/link` | `link` |
| `@tanstack/charts/mark/scale-values` | `createMarkWithScaleValues` |
| `@tanstack/charts/polar` | `polar`, radial arc/line/area/dot marks, and radial/angle guides |
| `@tanstack/charts/portable` | Compatibility alias for `@tanstack/charts/universal` |
| `@tanstack/charts/universal` | Common root authoring, runtime, scene, and static SVG values without browser hosts or adapters |
| `@tanstack/charts/reconcile` | `reconcileChartSvg` |
| `@tanstack/charts/rect` | `rect`, `cell` |
Expand Down
5 changes: 5 additions & 0 deletions packages/charts-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"./link": "./src/link.ts",
"./mark/scale-values": "./src/mark-with-scale-values.ts",
"./polar": "./src/polar.ts",
"./portable": "./src/portable.ts",
"./universal": "./src/universal.ts",
"./reconcile": "./src/reconcile.ts",
"./rect": "./src/rect.ts",
Expand Down Expand Up @@ -199,6 +200,10 @@
"types": "./dist/polar.d.ts",
"import": "./dist/polar.js"
},
"./portable": {
"types": "./dist/portable.d.ts",
"import": "./dist/portable.js"
},
"./universal": {
"types": "./dist/universal.d.ts",
"import": "./dist/universal.js"
Expand Down
6 changes: 4 additions & 2 deletions packages/charts-core/src/exports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ describe('public package exports', () => {
).toBe(true)
})

it('keeps the universal barrel aligned with root authoring exports', async () => {
const [root, universal] = await Promise.all([
it('keeps the environment-safe barrels aligned with root authoring exports', async () => {
const [root, portable, universal] = await Promise.all([
import('@tanstack/charts'),
import('@tanstack/charts/portable'),
import('@tanstack/charts/universal'),
])
const browserOnlyRootValues = new Set([
Expand All @@ -41,6 +42,7 @@ describe('public package exports', () => {
.filter((name) => !browserOnlyRootValues.has(name))
.sort(),
)
expect(Object.keys(portable).sort()).toEqual(Object.keys(universal).sort())
})

it('keeps tooltip capabilities on exact subpaths', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/charts-core/src/portable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './universal'
3 changes: 2 additions & 1 deletion scripts/check-packed-consumers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ async function verifyDeclarations() {
type ChartPoint,
type ChartTooltipOptions,
} from '@tanstack/charts/universal'
import { defineChart as definePortableChart } from '@tanstack/charts/portable'
import type {
ChartDefinition,
ChartScene,
Expand Down Expand Up @@ -1159,7 +1160,7 @@ async function verifyDeclarations() {
id: 'host-tooltip-portal',
create: () => undefined,
}
void [point, tooltip, tooltipToken, portalToken]
void [point, tooltip, tooltipToken, portalToken, definePortableChart]
`
const universalContractPath = resolve(
fixtureDirectory,
Expand Down