Cedar 17
Modular component imports, first-class TypeScript contracts, and the Cedar Tokens v14 architecture| package name | version |
|---|---|
@rei/cedar | ^17.x.x |
@rei/cdr-tokens | ^14.x.x |
@rei/cdr-component-variables | ^11.x.x |
External modules that use Cedar should list it as a peerDependency so your application controls the resolved version.
Cedar 17 is mostly a package-structure release: the components are the same building blocks, but the public import paths, generated declarations, and token package outputs are much stricter.
Read the breaking changes, then use the migration guide below as the single source for upgrade steps. For detailed installation instructions, see the Installing Cedar page. For a complete list of deprecated APIs, see the Deprecated items page.
Modular component imports
Root imports continue to work, and Cedar now also publishes component-level entrypoints for smaller bundles and clearer dependency boundaries. See the Installing Cedar page for usage examples.
import { CdrButton, CdrAccordion } from '@rei/cedar';
import CdrButton from '@rei/cedar/CdrButton';
import CdrAccordion from '@rei/cedar/CdrAccordion';
The modular paths use PascalCase component names matching the Vue component names. For example, use @rei/cedar/CdrButton, not @rei/cedar/button.
| Component | Modular import |
|---|---|
CdrButton | @rei/cedar/CdrButton |
CdrAccordionGroup | @rei/cedar/CdrAccordionGroup |
CdrFulfillmentTile | @rei/cedar/CdrFulfillmentTile |
CdrMediaObject | @rei/cedar/CdrMediaObject |
CdrSurfaceNavigation | @rei/cedar/CdrSurfaceNavigation |
First-class TypeScript support
Cedar 17 publishes generated declarations for the package root and each component entrypoint. Component prop types, shared option types, and token-derived values are part of the public API instead of package-internal files. See the Installing Cedar page for TypeScript usage examples.
import type { CdrButtonProps, Breakpoint, Space, TypeScale } from '@rei/cedar';
import CdrButton, {
type CdrButtonProps as ButtonProps,
} from '@rei/cedar/CdrButton';
Each modular entrypoint exports the component as the default export, the named component export, and the component's public types.
Modal SSR hydration fix
CdrModal now avoids the Teleport race condition that caused server/client markup divergence in Vue SSR and Nuxt pages.
Storybook-based component reference
The Cedar component reference is now backed by Storybook 10 on GitHub Pages. Component docs and isolated examples are available at https://rei.github.io/rei-cedar/. For links to all Cedar Storybook instances and GitHub repos, see the Developer onboarding page.
Tooling modernization
Cedar's source repo now standardizes on pnpm, Vite, Vitest, Storybook 10, Oxlint, Stylelint, and vue-tsc. Contributors building Cedar locally should use Node >=22.12.0 <23 and pnpm.
Upgrade Tokens with Cedar
Cedar 17 imports token values from the modular paths introduced in @rei/cdr-tokens@14. A consuming application that upgrades Cedar without upgrading tokens will fail during import resolution.
Deep Cedar imports are blocked
Cedar's exports map now defines the supported public API. Internal paths such as @rei/cedar/dist/components/*, @rei/cedar/dist/types/*, @rei/cedar/src/*, and other implementation details should not be imported directly.
Full Cedar stylesheet renamed
The full bundled stylesheet is now cedar.css.
Type export barrels replaced
The old types/interfaces and types/other barrels are no longer public entrypoints. Import component prop types and shared types from the package root, or from the matching modular component entrypoint.
Text preset scale props use token-style values
Text preset scale props now use Cedar's token-derived scale values instead of bare numeric strings.
Affected components include CdrBody, CdrSubheadingSans, CdrUtilitySans, CdrUtilitySerif, CdrHeadingDisplay, CdrHeadingSans, CdrHeadingSerif, and related content scale options on CdrFulfillmentTile.
ScaleValue type removed
The old ScaleValue type has been removed. TypeScale is the public type.
import type { TypeScale } from '@rei/cedar';
Fluid CSS custom property names updated
Negative type scale CSS custom properties now use minus in the token name.
Compound space scale CSS custom properties now match token package output with a single hyphen between numeric ranges.
Cedar component props keep the descriptive option names, such as scale-3--5, while emitted CSS variables use the canonical token names, such as --cdr-space-scale-3-5.
@rei/cdr-tokens@14 is the aligned token release for Cedar 17. The main change is a modular token architecture: foundation, component, and palette outputs are split into explicit CSS, SCSS, JavaScript, JSON, and TypeScript artifacts with a stricter package exports map.
Token package outputs
| Need | Import |
|---|---|
| Full CSS custom properties | @rei/cdr-tokens/css |
| Single CSS foundation | @rei/cdr-tokens/css/color-background, @rei/cdr-tokens/css/type, or @rei/cdr-tokens/css/space-scale |
| Full SCSS bundle | @rei/cdr-tokens/scss |
| SCSS utility mixins | @rei/cdr-tokens/scss/breakpoint-mixins or @rei/cdr-tokens/scss/type-mixins |
| Themed SCSS foundation partial | @rei/cdr-tokens/rei-dot-com/scss/foundations/cdr-space.scss |
| Generated JavaScript constants | @rei/cdr-tokens/tokens |
| Themed JavaScript foundation module | @rei/cdr-tokens/rei-dot-com/js/foundations/cdr-space |
| Semantic foundation objects and order | @rei/cdr-tokens/types |
| Single TypeScript foundation module | @rei/cdr-tokens/types/space |
| Generated token types | @rei/cdr-tokens/types and type-only paths such as @rei/cdr-tokens/types/space.keys |
| JSON token data | @rei/cdr-tokens/json and @rei/cdr-tokens/json/foundations/cdr-space.json |
| Docsite token assets | @rei/cdr-tokens/docsite/css and @rei/cdr-tokens/docsite/scss |
LESS output is no longer distributed.
Use @rei/cdr-tokens/types when you need semantic foundation objects at runtime, such as CdrBreakpointOrder. Use @rei/cdr-tokens/tokens when you need generated JavaScript constants, such as CdrBreakpointLg or CdrSpaceOneX.
Per-foundation modules
Foundation token outputs now live under foundations/ in each output format. CSS, SCSS, JavaScript, JSON, and TypeScript all include foundation files such as cdr-breakpoint, cdr-color-background, cdr-radius, cdr-space, cdr-space-scale, cdr-text-size, cdr-type, cdr-motion-duration, and cdr-prominence.
import '@rei/cdr-tokens/css/color-background';
import { CdrSpaceOneX } from '@rei/cdr-tokens/tokens';
import type { CdrSpaceKey } from '@rei/cdr-tokens/types/space.keys';
Kebab-case key unions
Generated .keys modules export strict token-key unions for each foundation. This lets TypeScript consumers and utility generators work with token keys directly instead of transforming PascalCase constant names.
import type { CdrSpaceKey } from '@rei/cdr-tokens/types/space.keys';
const space: CdrSpaceKey = 'one-x';
The unions are strict. A value like 'oneX' or 'OneX' is now a type error.
Canonical breakpoint order
CdrBreakpointOrder is exported as a typed const tuple in the semantic token contract. Use it instead of hardcoding ['xs', 'sm', 'md', 'lg'] in responsive logic.
import { CdrBreakpointOrder } from '@rei/cdr-tokens/types';
CdrBreakpointOrder.forEach((breakpoint) => {
// breakpoint is typed as 'xs' | 'sm' | 'md' | 'lg'
});
DTCG-aligned typography tokens
Typography JSON now uses the W3C Design Token Community Group $type and $value shape. Tools such as Tokens Studio, Figma Variables workflows, and token pipelines that consume DTCG-style JSON can read Cedar typography output with less project-owned translation code.
Component variables v11
Component variables v11 is the aligned release for Cedar 17 and cdr-tokens 14.
Direct token dist/ imports are no longer public
The token package now relies on explicit package exports. Use per-category imports like @rei/cdr-tokens/css/color instead of direct dist/ paths. If your bundler doesn't support exports (older Webpack 4), you can reference dist/ paths directly using the new foundations/ structure.
Runtime constants moved behind tokens
Generated JavaScript constants are exposed through @rei/cdr-tokens/tokens.
The @rei/cdr-tokens/types export describes the semantic foundation contract. If your application needs the generated constant names that existed in the older JS bundle, use @rei/cdr-tokens/tokens.
JSON output is nested
Token JSON output now includes nested components/ and foundations/ directories in addition to platform-level JSON files.
SCSS shortcut paths are limited
The short @rei/cdr-tokens/scss/* path is for utility mixins such as breakpoint-mixins, display-mixins, and type-mixins. Foundation SCSS partials are exposed through themed paths.
CdrModal
No props, slots, or events changed.
CdrModal SSR hydration
Fixed a CdrModal Teleport race condition that could cause hydration mismatches on server-rendered Vue and Nuxt pages.
No Cedar component visual redesigns are included in this release. The design-system changes are token contract changes: typography JSON is DTCG-aligned, type and space custom property names are canonicalized, and component variables remain aligned with Tokens 14.
1. Upgrade in a branch
Start in a new branch, following the same approach recommended by Tailwind's v3 to v4 upgrade guide. Update the Cedar packages together, then review the application diff before merging. Use your application's package manager; for npm:
npm install @rei/cedar@17 @rei/cdr-tokens@14 @rei/cdr-component-variables@11
Update external modules that also use Cedar to the same major version.
2. Replace the full Cedar stylesheet
- import '@rei/cedar/dist/cdr-style.css';
+ import '@rei/cedar/dist/cedar.css';
Keep any explicit reset, font, palette, or component CSS imports that your application already owns, as long as they use public CSS paths.
Supported core CSS imports include:
import '@rei/cedar/dist/cdr-reset.css';
import '@rei/cedar/dist/cdr-fonts.css';
import '@rei/cedar/dist/cedar.css';
Component CSS is still available from @rei/cedar/dist/style/*:
import '@rei/cedar/dist/style/cdr-button.css';
If you imported the old standalone fluid variable file, replace it with token CSS:
- import '@rei/cedar/dist/style/cdr-fluid-vars.css';
+ import '@rei/cdr-tokens/css/type';
+ import '@rei/cdr-tokens/css/space-scale';
You can also import the full token CSS bundle with @rei/cdr-tokens/css if your application needs all token custom properties.
3. Replace internal Cedar imports
| Previous pattern | Replacement |
|---|---|
@rei/cedar/dist/components/button/CdrButton.vue | @rei/cedar/CdrButton or { CdrButton } from '@rei/cedar' |
@rei/cedar/dist/lib.mjs | Named imports from @rei/cedar |
@rei/cedar/dist/types/* | Type exports from @rei/cedar or @rei/cedar/CdrButton/types |
@rei/cedar/dist/component-docgen.json | Use the public Storybook docs instead; the package-internal docgen file is not a public API |
- import CdrButton from '@rei/cedar/dist/components/button/CdrButton.vue';
+ import CdrButton from '@rei/cedar/CdrButton';
Root imports remain supported:
import { CdrButton } from '@rei/cedar';
4. Update Cedar type imports
- import type { CdrButtonProps } from '@rei/cedar/types/interfaces';
- import type { CdrAccordionProps } from '@rei/cedar/types/other';
+ import type { CdrButtonProps, CdrAccordionProps } from '@rei/cedar';
For component-local imports:
import CdrButton, { type CdrButtonProps } from '@rei/cedar/CdrButton';
5. Update text scale values
| Previous value | New value |
|---|---|
-2 | scale-minus-2 |
-1 | scale-minus-1 |
0 | scale-0 |
1 | scale-1 |
2 | scale-2 |
3 | scale-3 |
4 | scale-4 |
5 | scale-5 |
6 | scale-6 |
7 | scale-7 |
- <CdrBody scale="-1">Body copy</CdrBody>
- <CdrHeadingSans scale="2">Heading</CdrHeadingSans>
+ <CdrBody scale="scale-minus-1">Body copy</CdrBody>
+ <CdrHeadingSans scale="scale-2">Heading</CdrHeadingSans>
Replace ScaleValue with TypeScale anywhere you reference the shared type. Use Extract<TypeScale, ...> if a component should only accept a subset of Cedar type-scale values.
Update direct CSS custom property references if your app uses the old fluid token names:
| Previous CSS variable | Replacement |
|---|---|
--cdr-type-scale--1 | --cdr-type-scale-minus-1 |
--cdr-type-scale--2 | --cdr-type-scale-minus-2 |
| Cedar spacing option | CSS custom property |
|---|---|
scale-0--1 | --cdr-space-scale-0-1 |
scale-3--4 | --cdr-space-scale-3-4 |
scale-3--5 | --cdr-space-scale-3-5 |
6. Update token imports
| Previous import | Replacement |
|---|---|
@rei/cdr-tokens/dist/rei-dot-com/scss/cdr-tokens.scss | @rei/cdr-tokens/scss |
~@rei/cdr-tokens/dist/rei-dot-com/scss/cdr-tokens.scss | @rei/cdr-tokens/scss |
@rei/cdr-tokens/dist/rei-dot-com/css/cdr-tokens.css | @rei/cdr-tokens/css |
@rei/cdr-tokens/dist/docsite/scss/cdr-tokens.scss | @rei/cdr-tokens/docsite/scss |
@rei/cdr-tokens/dist/docsite/css/cdr-tokens.css | @rei/cdr-tokens/docsite/css |
- @use '~@rei/cdr-tokens/dist/rei-dot-com/scss/cdr-tokens.scss' as cdr;
+ @use '@rei/cdr-tokens/scss' as cdr;
- import { CdrBreakpointLg } from '@rei/cdr-tokens';
+ import { CdrBreakpointLg } from '@rei/cdr-tokens/tokens';
- import '@rei/cdr-tokens/dist/rei-dot-com/css/cdr-tokens.css';
+ import '@rei/cdr-tokens/css';
Use full foundation names for CSS shortcuts, such as @rei/cdr-tokens/css/color-background. A path like @rei/cdr-tokens/css/color is not a published file.
Use @rei/cdr-tokens/scss for the full SCSS bundle. The short @rei/cdr-tokens/scss/* path is only for utility mixins, such as breakpoint-mixins, display-mixins, and type-mixins.
Replace LESS imports with CSS, SCSS, JavaScript, TypeScript, or JSON token outputs.
7. Update token type imports
import type { CdrSpaceKey } from '@rei/cdr-tokens/types/space.keys';
import { CdrBreakpointOrder } from '@rei/cdr-tokens/types';
8. Copy token JSON recursively
If your build consumes token JSON artifacts, copy the full JSON tree so the new foundations/ and components/ directories are included. Use the exported JSON paths, such as @rei/cdr-tokens/json or @rei/cdr-tokens/json/foundations/cdr-space.json, instead of direct dist/ paths.
9. Remove modal SSR workarounds
If you wrapped CdrModal in ClientOnly only to avoid hydration mismatches, test removing that wrapper.
- <ClientOnly>
- <CdrModal :opened="opened" label="Example">
- ...
- </CdrModal>
- </ClientOnly>
+ <CdrModal :opened="opened" label="Example">
+ ...
+ </CdrModal>
10. Optionally adopt modular component imports
The barrel import still works. Modular component imports are opt-in and are useful when you want the consuming page to import only the components it uses.
- import { CdrButton, CdrAccordion } from '@rei/cedar';
+ import CdrButton from '@rei/cedar/CdrButton';
+ import CdrAccordion from '@rei/cedar/CdrAccordion';
11. Validate the upgrade
Run your application build and typecheck, then review the areas most likely to show migration issues: SSR or Nuxt pages with CdrModal, pages using text preset scale props, stylesheets that import Cedar or token CSS, and build scripts that copy token JSON artifacts. If your bundler does not support package exports, update its resolver before consuming Cedar 17 and Tokens 14.
Docsite-only Sass variables
Several docsite-only Sass variable names are no longer present in the v14 SCSS partials. Avoid adding new dependencies on these names. If a docs or marketing site still needs the exact legacy values, define project-owned CSS custom properties.
| Removed Sass variable | Legacy value |
|---|---|
$cdr-knockout-color-background-primary | #2e2e2b |
$cdr-knockout-color-border-inverse-primary | #4b4a48 |
$cdr-knockout-color-border-table-row | #4b4a48 |
$cdr-color-background-code | #2e2e2b |
$cdr-color-background-code-snippet | #edeae3 |
$cdr-color-border-note | #c4b03b |
$cdr-color-icon-background-note | #c4b03b |