A modern, extensible design system for building consistent, accessible user interfaces.
- Nimbus Design System
Nimbus is a comprehensive design system that provides a collection of reusable components, icons, and design tokens for building consistent user interfaces. This monorepo contains multiple packages and applications that work together to provide a cohesive design system experience.
| Package | Description | Purpose |
|---|---|---|
| @commercetools/nimbus | Core UI component library | Provides React components for building user interfaces |
| @commercetools/nimbus-icons | Icon library | SVG files wrapped as React components |
| tokens | Design tokens | Color, spacing, typography, and other design variables |
| color-tokens | Brand colors | Brand-specific color definitions |
| Application | Description | Purpose |
|---|---|---|
| docs | Documentation site | Interactive documentation for all Nimbus packages, auto-generated from MDX files in the packages |
Before you begin, ensure you have the following installed:
- Node.js: v22.14.0+
- PNPM: v9.12.3+
All commands should be run from the repository root.
-
Clone the repository:
git clone https://github.com/your-org/nimbus.git cd nimbus -
Initialize the repository:
pnpm nimbus:init
Tip
It is advisable to run the repo:init command after every branch-switch. The
command gets rid of all node_modules- & dist-folders, reinstalls
dependencies and rebuilds all packages.
Start the development environment with the following command:
pnpm startThis will start both the documentation app and Storybook in parallel:
- Documentation app: http://localhost:5173/
- Storybook: http://localhost:6006/
If you prefer to run just one of the applications:
# Start only the documentation app
pnpm start:docs
# Start only Storybook
pnpm start:storybookBuild all packages and applications:
pnpm buildBuild only specific parts of the system:
# Build only the packages (not the docs application)
pnpm build:packages
# Build only the documentation application
pnpm build:docs
# Build only the design tokens
pnpm build:tokensFor detailed guidance on creating new components, see the Component Guidelines.
Nimbus uses Vitest for testing with two distinct test types that serve different purposes.
- Purpose: Test component behavior, interactions, and visual states
- Environment: Real browser (headless Chromium with Playwright)
- Use for: ALL component testing - buttons, forms, dialogs, menus, etc.
- Location:
*.stories.tsxfiles withplayfunctions - Speed: Slower (~seconds per story)
- Purpose: Test utility functions and React hooks in isolation
- Environment: JSDOM (fast, simulated browser environment)
- Use for: Pure functions, custom hooks, validators, formatters
- Location:
*.spec.tsor*.spec.tsxfiles - Speed: Very fast (~milliseconds per test)
# Run all tests (unit + Storybook)
pnpm test
# Run only unit tests (fast)
pnpm test:unit
# Run only Storybook tests (slower, browser-based)
pnpm test:storybook
# Run specific test file
pnpm test packages/nimbus/src/components/button/button.stories.tsx
# Run tests with minimal console output
pnpm test --silent
# Run tests in watch mode (unit tests only)
pnpm test:unit --watch
# Run with coverage
pnpm test --coverage[!IMPORTANT] Storybook tests run against the BUILT bundle, not source files.
The Storybook configuration operates in two distinct modes:
| Mode | Command | Imports From | Purpose |
|---|---|---|---|
| Development | pnpm start:storybook |
Source files (src/) |
Live editing with HMR |
| Testing | pnpm test:storybook |
Built bundle (dist/) |
Test production-like code |
During testing, imports resolve to the built bundle in packages/nimbus/dist/.
This ensures:
- Tests validate actual published behavior
- Tests match how consumers use the package
- Tests catch build-related issues
# β WRONG - Tests will use stale code
# Make changes to component
pnpm test:storybook # Tests old code!
# β
CORRECT - Build first, then test
# 1. Make changes to component
# 2. Build the package
pnpm build:packages
# 3. Run tests
pnpm test:storybook
# Or combine in one command
pnpm build:packages && pnpm test:storybookThe system automatically detects test mode via:
configType === 'DEVELOPMENT'- Set by Vite based on commandVITEST_WORKER_ID- Set automatically by Vitest when running testsVITEST=true- Manual override for forcing test mode
Manual Override Example:
# Force test mode (use built bundle) even in development
VITEST=true pnpm start:storybook
# Normal development mode (use source files with HMR)
pnpm start:storybookWhen test mode is detected, Storybook uses the built bundle instead of source files.
Developer Visibility:
Storybook logs which mode is active on startup:
[Storybook] Running in DEVELOPMENT (HMR enabled, using source files)- Development mode with live reload[Storybook] Running in PRODUCTION/TEST (using built bundle)- Testing or production mode
This helps confirm whether your changes require a build before testing.
# Quick iteration cycle for component changes
pnpm --filter @commercetools/nimbus build && pnpm test:storybook
# Test specific component
pnpm --filter @commercetools/nimbus build && pnpm test packages/nimbus/src/components/menu/menu.stories.tsx
# Unit tests don't need building (they import source directly)
pnpm test:unit --watch
# Full test suite
pnpm test| Issue | Solution |
|---|---|
| β Tests pass but changes don't show | Build the package before testing |
| β Tests fail after working locally | Ensure pnpm build was run |
| β Expecting HMR during tests | Use pnpm start:storybook for live preview |
| β Build β Test β Iterate | This is the correct workflow |
To initialize or reset the entire project:
# Full initialization (reset, install dependencies, build)
pnpm nimbus:init
# Reset only (remove node_modules and dist folders)
pnpm nimbus:resetGenerate design tokens for the system:
pnpm generate:tokensThis command processes the token source files and outputs them in multiple formats:
- CSS custom properties
- TypeScript definitions
- Component-specific token files
Want to test your local Nimbus code changes in another repo (like Merchant
Center) before publishing? pnpm link --global lets you do this by creating a
direct connection (a symlink) between your local Nimbus and the other repo.
Follow these steps:
-
Build Nimbus: Make sure Nimbus and its internal packages have been built recently with your latest changes. (Via
pnpm buildcommand in the Nimbus repo). -
Register Nimbus Locally: In your Nimbus design system repository (at the root folder), run:
pnpm link --global
- What this does: This tells your computer where your local Nimbus code
lives and registers it globally under its package name (
nimbus). Think of it like a temporary, local "publishing" step just for your machine.
- What this does: This tells your computer where your local Nimbus code
lives and registers it globally under its package name (
-
Connect Your Project to Local Nimbus: In the target repository where you want to use your local Nimbus (such as Merchant Center), run:
pnpm link --global nimbus
- Important: You'll need to run this command within the application you
want to use it in rather than at the root level - for example, in the
application-project-settingsdirectory in the Merchant Center repo. - What this does: This connects this specific project to the local
Nimbus you just registered. It creates a special link (symlink) inside
this project's
node_modulesfolder that points directly to your local Nimbus code. - Verification: You can peek inside the target repo's
node_modulesfolder; you should seenimbuslisted (often visually indicated as a link).
- Important: You'll need to run this command within the application you
want to use it in rather than at the root level - for example, in the
-
Import and Use: Now, in your target repo's code, you can import and use Nimbus components.
// Correct way to import after linking:
import {
Box,
Avatar,
NimbusProvider,
Button,
LoadingSpinner,
} from '../../../node_modules/nimbus/packages/nimbus'; // <-- This is a relative path to the symlink - you'll have to adjust the depth as needed.
// Use the components...
function MyComponent() {
return (
<NimbusProvider>
<Box>
<Button>Hello Nimbus!</Button>
</Box>
</NimbusProvider>
);
}
```
5. **Testing changes**: Make changes to your local Nimbus code, then run
`pnpm build` in Nimbus to rebuild. You should now see changes reflected in
the target repo.
6. **Unlink when finished**:
```bash
# In the target project:
pnpm unlink -g nimbus
# In the Nimbus repository:
pnpm unlink --globalWe welcome contributions from all team members. To contribute:
- Create a new branch for your feature or fix
- Make your changes
- Write or update tests
- Update documentation
- Submit a pull request
Please follow our coding standards and commit message conventions.
| Problem | Solution |
|---|---|
| Component styles not updating | Make sure you've rebuilt the tokens with pnpm build:tokens |
| Documentation site not showing latest changes | Restart the development server with pnpm start |
| Build errors after pulling latest changes | Try running pnpm nimbus:init to reset, reinstall, and rebuild |
For additional help, please contact the Nimbus team or submit an issue in our repository.
