React component library implementing the commercetools Design System. These
components are consumed by Merchant Center custom applications and other
commercetools frontend products. Published to npm under @commercetools-uikit/*
(individual packages) and @commercetools-frontend/ui-kit (all-in-one preset).
- Toolchain: Node 24 (
.nvmrc), pnpm 10 (via Corepack βpackageManagerfield pins the version), React 19 peer dependency β verify these before installing. Do not assume React 18 patterns. - Dev loop:
pnpm startlaunches Storybook (the canonical visual playground). - Fast test feedback:
pnpm --filter @commercetools-uikit/<pkg> testruns a single package's tests without walking the whole repo.
This is a pnpm workspaces monorepo. Packages fall into these categories:
design-system/β Design tokens and shared styling utilities. Tokens are defined indesign-system/materials/internals/definition.yamland code-genned into TypeScript, CSS custom properties, and JSON viadesign-system/scripts/generate-design-tokens.js. All component packages depend on this.packages/components/β Individual UI components (buttons, inputs, fields, icons, spacings, etc.). Each is published as its own npm package. Fields compose an input with a label + error display. Components use Emotion for CSS-in-JS andreact-intlfor i18n.packages/(top-level) β Shared utilities (utils,hooks,localized-utils,calendar-utils,calendar-time-utils) and thei18npackage containing all translation messages.presets/β Convenience packages that re-export groups of component packages (e.g.@commercetools-uikit/buttonsre-exports all button types).presets/ui-kitis the all-in-one@commercetools-frontend/ui-kitpackage.storybook/β Storybook playground (private, not published).visual-testing-app/β Vite app used by Percy for visual regression testing (private).generators/β Scaffolding tools for package.json and README generation (private).
Data flow for design tokens: YAML definitions β
generate-design-tokens.js β TypeScript source (design-system/src/) + CSS
custom properties (design-system/materials/). Components import tokens from
@commercetools-uikit/design-system.
Data flow for icons: raw SVGs (packages/components/icons/src/svg/*.react.svg)
β svgr with custom template (svgr.config.js) β generated React components
(packages/components/icons/src/generated/).
Data flow for i18n: component messages.ts files β formatjs extract β
packages/i18n/data/core.json β translated JSON files per locale β
formatjs compile-folder β packages/i18n/compiled-data/.
All publishable packages are built via Preconstruct. Changesets manages
versioning β all @commercetools-frontend/* and @commercetools-uikit/*
packages are in a fixed version group (they share the same version number).
| Task | Command | Notes |
|---|---|---|
| Test one package | pnpm --filter @commercetools-uikit/<pkg> run test |
Fastest feedback for a single package |
| Test by path | pnpm test packages/components/buttons |
Positional path; matches any tests under it |
| Typecheck | pnpm typecheck |
Runs tsc --noEmit --skipLibCheck |
| Lint | pnpm lint |
Uses Jest runner for ESLint |
| Visual test suite | pnpm test:visual |
Runs --runInBand; needs visual-testing-app |
Add a new icon:
- Add the raw SVG to
packages/components/icons/src/svg/β file must end with.react.svg - Run
pnpm generate-iconsto generate the React component inpackages/components/icons/src/generated/ - Run
pnpm preconstruct devto create entrypoint stubs
Update design tokens:
- Edit
design-system/materials/internals/definition.yaml - Run
pnpm design-tokens:buildto regenerate TypeScript + CSS outputs - Run
pnpm typecheckβ token changes can break components
Add or update translations:
- Define messages in the component's
messages.ts - Run
pnpm extract-intlto updatepackages/i18n/data/core.json - Add translations to the locale JSON files in
packages/i18n/data/ - Run
pnpm compile-intlto produce compiled output
Add a changeset for a PR:
- Run
pnpm changeset - Select affected packages, semver bump type, and describe the change
- Commit the generated
.changeset/*.mdfile with the PR
Full build (rarely needed locally):
Run pnpm build β wraps codegen and preconstruct build into one step.
- All
@commercetools-uikit/*and@commercetools-frontend/ui-kitpackages are published to npm under a fixed version group β every semver bump applies to all packages. Treat all public API changes as semver-significant. storybook/,visual-testing-app/, andgenerators/are private β not published, no semver obligations.- Components should be domain-agnostic β no commercetools business logic. They implement the design system, not product features.
- Peer dependencies: consumers must provide
react,react-dom, and typicallyreact-intl. Do not bundle these.
- Generated files must not be hand-edited. Icon components in
packages/components/icons/src/generated/and design token outputs are overwritten by codegen scripts. Edit the SVG source ordefinition.yamlinstead. - Icon SVG filenames have a convention: they must end with
.react.svg. The filename drives the exported component name (e.g.angle-down.react.svgβAngleDownIcon). - All publishable packages share a single version. The changeset
fixedconfig groups@commercetools-frontend/*and@commercetools-uikit/*together β a bump to one bumps all. - Lint runs through Jest runners, not directly via
eslintCLI. Usepnpm lint:jsorpnpm lint, notnpx eslint. - Pre-commit hooks run Prettier, lint (via Jest), and
tsc-fileson staged.ts/.tsxfiles. Expect these to block if types are broken. - Visual specs (
.visualspec.js/.visualroute.jsx) are consumed by Percy for visual regression testing. If you change component appearance, the visual spec may need updating and Percy snapshots must be approved. - Workspace constraints enforce metadata consistency (license, repository fields, publishConfig) across all public packages.
- Commit messages follow Conventional Commits
β enforced by commitlint. Scopes may contain slashes (e.g.
refactor(app/my-component): ...). - Component files follow a naming pattern:
<component-name>.tsx,<component-name>.spec.js,<component-name>.stories.tsx,<component-name>.styles.ts,<component-name>.visualroute.jsx,<component-name>.visualspec.js. - Each component has an
export-types.tsthat re-exports its public types and aversion.tsthat re-exports the package version. - Tests use
@testing-library/reactβ behavior-driven, no shallow rendering. - CSS-in-JS uses Emotion (
@emotion/reactwithcssprop /ClassNames).
design-system/materials/internals/TOKENS.mdβ design token structure reference.changeset/README.mdβ changesets workflow