Split tokens into it's own library

Design tokens are currently defined in the /packages/gitlab-ui package within the design system. The design system is using npm workspaces to manage multiple child packages for example /packages/gitlab-ui, /packages/gitlab-svgs etc.

Within /packages/gitlab-ui is the /src/tokens directory which contains both the design token JSON definitions and the style-dictionary built output (in the /src/tokens/build directory). The build step is contained within /packages/gitlab-ui/bin/build_tokens.mjs which also used helper functions contained in /packages/gitlab-ui/bin/lib/.

Consumers wishing to use design tokens without GitLab UI components could consume a separate package e.g /packages/gitlab-design-tokens which contains the design token JSON definitions, style-dictionary dependency and build script build_tokens.mjs (with helper functions), and generated output in a /build directory. This means consumers can use a @gitlab/design-tokens npm package directly without needing to use @gitlab/ui with all components.

Approach

This approach outlines the extraction of design tokens from the @gitlab/ui package into a separate @gitlab/design-tokens package. This change allows consumers to use GitLab design tokens without requiring the full GitLab UI component library.

New Package Structure

Created packages/gitlab-design-tokens/ with the following structure:

packages/gitlab-design-tokens/
├── package.json
├── README.md
├── index.mjs # Build script
├── lib/              # Helper functions
├── src/
│   ├── constant/     # Base design tokens
│   ├── semantic/     # Contextual tokens
│   ├── contextual/   # Component-specific tokens
│   └── deprecated/   # Legacy tokens
└── build/            # Generated output (created on build)
    ├── css/
    ├── scss/
    ├── js/
    ├── json/
    ├── tailwind/
    └── figma/

Package Configuration

New Package (@gitlab/design-tokens):

  • Version: 1.0.0
  • Main entry: build/js/tokens.js
  • Dependencies: style-dictionary, glob, lodash, prettier
  • Build script: yarn build (runs bin/build_tokens.mjs)
  • Published files: build/, src/tokens/, bin/

Updated Dependencies

Root workspace:

  • Added packages/gitlab-design-tokens to workspaces

GitLab UI package:

  • Added @gitlab/design-tokens: "*" as dependency
  • Updated Makefile to copy tokens from design-tokens package instead of building locally
  • Removed token building logic from build process

Build Process Changes

Design Tokens Package:

  • Builds all token formats (CSS, SCSS, JS, JSON, Tailwind, Figma)
  • Output goes to build/ directory
  • No longer copies to separate dist/ directory

GitLab UI Package:

  • Copies pre-built tokens from ../gitlab-design-tokens/build/
  • Maintains existing file structure for backward compatibility
  • Tokens available at src/tokens/build/ and dist/tokens/

Usage Examples

For Design Token Consumers Only

npm install @gitlab/design-tokens
/* CSS Custom Properties */
@import '@gitlab/design-tokens/build/css/tokens.css';

.my-component {
  color: var(--gl-text-color-primary);
  background: var(--gl-background-color-default);
}
// JavaScript/TypeScript
import tokens from '@gitlab/design-tokens/build/js/tokens.js';

const styles = {
  color: tokens.GL_TEXT_COLOR_PRIMARY,
  background: tokens.GL_BACKGROUND_COLOR_DEFAULT,
};
// Tailwind CSS
const gitlabTokens = require('@gitlab/design-tokens/build/tailwind/tokens.cjs');

module.exports = {
  theme: {
    extend: {
      colors: gitlabTokens.colors,
      spacing: gitlabTokens.spacing,
    },
  },
};

For GitLab UI Consumers

No changes required - tokens are still available through @gitlab/ui package at the same paths.

Breaking Changes

None for Existing Consumers

  • All existing import paths for tokens through @gitlab/ui continue to work
  • File structure and output formats remain identical
  • No API changes to token names or values

Potential Future Breaking Changes

If consumers were directly importing from:

  • @gitlab/ui/src/tokens/ (source files) - Not recommended, but possible
  • @gitlab/ui/bin/build_tokens.mjs - Internal build script, not public API

These paths will continue to work but are now sourced from the design-tokens package.

Trade-offs and Risks

Benefits

  1. Reduced Bundle Size: Consumers only need design tokens can avoid the full UI library
  2. Faster Installation: Fewer dependencies for token-only consumers
  3. Independent Versioning: Design tokens can be versioned separately from UI components
  4. Better Separation of Concerns: Clear distinction between design tokens and components
  5. Improved Developer Experience: Dedicated package with focused documentation

Risks and Considerations

  1. Increased Complexity:

    • Additional package to maintain
    • More complex build pipeline
    • Potential for version mismatches between packages
  2. Dependency Management:

    • GitLab UI now depends on design-tokens package
    • Risk of circular dependencies if not managed carefully
    • Need to ensure design-tokens is built before GitLab UI
  3. Breaking Changes for Edge Cases:

    • Direct imports from internal paths may break
    • Build process changes could affect custom tooling
  4. Migration Overhead:

    • Teams need to understand new package structure
    • Documentation updates required
    • Potential confusion during transition period
  5. Version Synchronization:

    • Need to coordinate releases between packages
    • Risk of incompatible token/component combinations

Migration Strategy

Phase 1: Soft Launch (Current)

  • New package available but not widely promoted
  • GitLab UI continues to work exactly as before
  • Early adopters can start using @gitlab/design-tokens

Phase 2: Documentation and Promotion

  • Update documentation to recommend new package for token-only use cases
  • Add migration guides and examples
  • Communicate benefits to development teams

Phase 3: Optimization (Future)

  • Consider removing token files from GitLab UI package
  • Optimize build processes
  • Evaluate feedback and make improvements

Development Workflow

Making Token Changes

  1. Edit tokens in packages/gitlab-design-tokens/src/tokens/
  2. Build tokens: cd packages/gitlab-design-tokens && yarn build
  3. Update GitLab UI: cd packages/gitlab-ui && make tokens
  4. Test changes in both packages

Publishing Process

  1. Build design tokens: Ensure packages/gitlab-design-tokens/build/ is up to date
  2. Version design tokens: Update version in packages/gitlab-design-tokens/package.json
  3. Update GitLab UI: May need to update dependency version
  4. Publish both packages: Coordinate release timing

Monitoring and Success Metrics

Technical Metrics

  • Build time improvements for token-only consumers
  • Bundle size reduction measurements
  • Installation time comparisons

Adoption Metrics

  • Download statistics for @gitlab/design-tokens
  • Usage patterns and feedback from consumers
  • Migration rate from full UI package to tokens-only

Quality Metrics

  • No regressions in existing GitLab UI functionality
  • Successful token updates across both packages
  • Community feedback and issue reports

Rollback Plan

If issues arise, the rollback process involves:

  1. Revert GitLab UI changes: Restore original Makefile and build process
  2. Remove design-tokens dependency: Update package.json
  3. Restore token building: Re-enable local token generation
  4. Deprecate design-tokens package: Mark as deprecated in npm

The original token files and build scripts are preserved, making rollback straightforward.

Conclusion

This extraction provides significant benefits for consumers who only need design tokens while maintaining full backward compatibility for existing GitLab UI users. The implementation minimizes risk through careful dependency management and preserves all existing APIs and file structures.

The success of this change will be measured by adoption rates, performance improvements, and the absence of breaking changes for existing consumers.

Edited by Scott de Jonge