Follow-up to the 1.3.0 framework-free work. Verified against the published basalt-ui@1.3.0 from npm, installed into an empty directory with no React present.
What works
All 24 peers are optional — peerDependenciesMeta marks every one, and npm reports zero required peers. That part of the change is correct.
What it doesn't achieve
Optional peers don't reduce the install, because npm installs a package's full dependencies regardless of which subpath the consumer imports. A consumer that wants only the tokens gets:
$ npm i basalt-ui@1.3.0 # in an empty project, no react
added 56 packages
$ npm ls react
basalt-ui@1.3.0
└─┬ @visx/axis@4.0.0
└── react@19.2.8
56 packages, 30 top-level, React 19 in the tree. The hard dependencies are @visx/* (×9), motion, remend, and three @fontsource-variable/*. @visx declares React as its own dependency, so it arrives transitively no matter what the peer metadata says.
So the documented framework-free path — install the package, import basalt-ui/tokens, emit CSS — still drags the entire React chart stack in for a static site that renders no components.
Two ways out
A. Move the chart and font deps to optional peers. Consistent with how @mantine/* is already handled, and it makes the dependency graph match the modularity the exports map already claims. Cost: basalt-ui/charts consumers install @visx/* themselves.
B. Document that the framework-free path shouldn't install the package at all. Now that dist/tokens.css is prebuilt and shipped and tokens:css exists, a static site can vendor the emitted file, or generate it in a repo that carries basalt as a devDependency, and ship zero runtime dependency. The install weight becomes irrelevant for the case it was blocking.
B is free and is what a static site actually wants; A is the more honest fix if basalt-ui/tokens is meant to be a supported runtime import. Currently docs/FRAMEWORK-FREE.md implies the install is lightweight, which measurement doesn't support either way.
Filed from the jkrumm.com side — see docs/basalt-astro.md in that repo for the original consumer evaluation.
Follow-up to the 1.3.0 framework-free work. Verified against the published
basalt-ui@1.3.0from npm, installed into an empty directory with no React present.What works
All 24 peers are optional —
peerDependenciesMetamarks every one, and npm reports zero required peers. That part of the change is correct.What it doesn't achieve
Optional peers don't reduce the install, because npm installs a package's full
dependenciesregardless of which subpath the consumer imports. A consumer that wants only the tokens gets:56 packages, 30 top-level, React 19 in the tree. The hard
dependenciesare@visx/*(×9),motion,remend, and three@fontsource-variable/*.@visxdeclares React as its own dependency, so it arrives transitively no matter what the peer metadata says.So the documented framework-free path — install the package, import
basalt-ui/tokens, emit CSS — still drags the entire React chart stack in for a static site that renders no components.Two ways out
A. Move the chart and font deps to optional peers. Consistent with how
@mantine/*is already handled, and it makes the dependency graph match the modularity the exports map already claims. Cost:basalt-ui/chartsconsumers install@visx/*themselves.B. Document that the framework-free path shouldn't install the package at all. Now that
dist/tokens.cssis prebuilt and shipped andtokens:cssexists, a static site can vendor the emitted file, or generate it in a repo that carries basalt as a devDependency, and ship zero runtime dependency. The install weight becomes irrelevant for the case it was blocking.B is free and is what a static site actually wants; A is the more honest fix if
basalt-ui/tokensis meant to be a supported runtime import. Currentlydocs/FRAMEWORK-FREE.mdimplies the install is lightweight, which measurement doesn't support either way.Filed from the jkrumm.com side — see
docs/basalt-astro.mdin that repo for the original consumer evaluation.