Versioning & upgrades
What counts as the public API — the surface a version bump can break — and why moving off the framework stays cheap.
What is (and isn't) API
- API (breaking it = a major version): semantic tokens,
documented class names, and
data-*/ARIA contracts. The API tables on every component page are generated from the shipped CSS, so what's documented is exactly what's contractual. - JS is API too: the exported
init*/refresh*function signatures and thebo:*intent-event payload shapes (the generated table on JS behaviors). Removing or reshaping an event'sdetailfield is a Breaking change and gets a CHANGELOG Breaking entry — pre-1.0 that means a minor bump with the entry; post-1.0, a major. - Not API: component-internal selectors and the raw palette
tier (
--bo-palette-*may change in any release — style against the semantic tier). Per-component dist file placement is also not API until v1.0 — à-la-carte importers should pin versions.
Docs policy — versioned snapshots
The root docs always describe the latest version; the version
switcher in the header serves pinned readers a frozen snapshot at
/v/<version>/ (search is a latest-docs feature —
snapshots ship without it). The
CHANGELOG
records every pre-1.0 breaking change either way. Release
flow: before tagging, run
node scripts/cut-version-snapshot.mjs <x.y.z> in
apps/docs, add the version to
apps/docs/versions.json, rebuild plain, and commit — the
Pages deploy copies every committed snapshot to
/v/<version>/ automatically.
⚠ Known gap — the current 0.1.1 snapshot: it was cut late as a mechanism proof and includes docs for later unreleased work — it gets re-cut correctly at the next release; snapshots are only version-faithful when cut AT their release, which is the documented flow above. Also by nature of static snapshots: a snapshot's own version dropdown freezes at cut time (a v0.1.1 reader won't see versions released later listed inside it) — the banner on every snapshot page links back to the always-current latest docs.
Leaving is cheap — by design
The cascade contract means your unlayered CSS already outranks the framework; a migration away is incremental overrides, not a rewrite. That's deliberate: an exit story you can verify beats a lock-in you have to trust.