Need private packages and team management tools?Check out npm Orgs. »


7.7.2 • Public • Published


gitlab-ui is a UI component library written in Vue.js. See for documentation.


Make sure you have Node 8.x (LTS) and Yarn 1.2 or newer.

Quick start

# Clone the project 
git clone
# Navigate to the root of the project 
cd gitlab-ui
# Install all the dependencies of the project 
yarn # or yarn install 
# Build and launch storybook to see the components in the browser 
yarn storybook

Go to http://localhost:9001/


Unit tests

Components’ unit tests live in the tests/components. The tests are organized following the same directory structure used to organize components.

yarn test:unit runs all unit tests.

yarn test:unit:watch runs all unit tests in watch mode.

yarn test:unit:debug runs all unit tests and allow to attach a debugger to the test runner process.

yarn jest [name_pattern] runs spec files that match the specified name pattern.


yarn jest datepicker will match all spec files with a name that contains the word datepicker.

yarn jest datepicker -t "when draw event is emitted" goes a step further and only runs the test with a description that matches the argument passed to the t flag.

SCSS tests

Even though we try to avoid writing complex SASS code to maintain CSS complexity low, we’ve implemented some functions that benefit from automated testing. SASS tests live in the tests/scss directory. gitlab-ui use sass-true to implement these tests, and jest run them.

yarn jest run_scss_tests runs all SCSS tests.

Visual regression tests

gitlab-ui uses visual snapshot tests to prevent introducing unexpected regressions with CSS and layout changes on components. The tool we use is storyshots, a storybook addon. Read the project documentation to understand how visual snapshots work.

There is a visual snapshot of every component’s storybook story. To run the tests, use the yarn test:visual command. This command runs on the CI environment and will fail if the component visual appearance changes.

Updating visual snapshot baseline images

In some occasions, the changes in a component’s appearance are justified. In those cases, we have to update the baseline images to match the new look. To do that, follow this troubleshooting guide

Gitlab visual regression tests

gitlab-ui components are a reference implementation of the Pajamas Design System components. These components should conform with the design system specs, and they should look correct in the pajamas website and the gitlab product. To make sure gitlab-ui’s components look precisely as their design specs dictate in gitlab, we created the yarn run test:visual:gitlab command.

This command only runs visual tests for components that have the followsDesignSystem: true flag activated in their *.documentation.js file. It will include gitlab product’s final CSS output in storybook and run the visual snapshots against this version.

The tests will fail if after including gitlab CSS, one or more components look different. These failures highlight how CSS that leaks from gitlab will affect a component’s final look in the product.

Running visual regression tests locally

Visual difference tests form part of the test suite. Rendered output can vary from host to host (e.g., due to available fonts and how each platform renders them), so these can fail when run locally. The easiest way to work around this is to increase the failure threshold with the FAILURE_THRESHOLD environment variable:

# Sets a 2% threshold 

If the variable is unset, it defaults to 0.


Install with Yarn:

yarn add @gitlab/ui

Install with NPM:

npm install @gitlab/ui

Adding CSS

From GitLab 12.2 on, we are moving components styles into GitLab UI, as described in the approved RFC #2. This approach will let us progressively decouple GitLab UI's styles from GitLab CE's styles.

Within the components' CSS, you should include utility mixins. See utility-mixins for a comprehensive list of the available utilities. If what you are looking for is not available, add it following the naming conventions indicated in that file.

Files should be structured like this:

├── components
│   └── base
│       ├── button
│       │   ├── button.scss
│       │   ├── button.stories.js
│       │   └── button.vue
│       └── popover
│           ├── popover.scss
│           ├── popover.stories.js
│           └── popover.vue
└── assets
    └── gitlab_ui.scss

Where each component's stylesheet contains its "modularized" style:

// button.scss 
.gl-button {
  // style 
  @include some-utility-mixin;

And the assets/components.scss file imports all components' stylesheets:

// components.scss 
@import '../components/base/button/button';
@import '../components/base/popover/popover';

Within the component and when the component is integrated into the application, you should still follow the utility-first approach for basic layout and other styles.

See !623 for an example and !624 for the first pass implementation of silent classes. Follow along with the development epic at &1590.

Why are we doing it like this?

The current SCSS architecture was designed to allow us both to gain the advantages of a utility CSS approach while also applying the same styles to both Vue components here in gitlab-ui and HAML components in gitlab.

With utility-first CSS, styles are applied as a combination of single-attribute classes:

.flex {
  display: flex;

.hot-pink {
  color: $gl-pink-500


<my-component class='flex hot-pink ...' />

The advantages of this approach are:

  • It keeps CSS file-size from growing too fast. With combinations applied in markup instead of separately named classes, new CSS usually does not need to be added.

  • It clarifies which colors, sizes, and other options are available within the design system. Rather than pulling values from specs or guessing, engineers are able to use already-vetted values. This also means that adding a new value becomes more deliberate and easier to check in reviews.

  • It increases confidence that adding or removing a class will not have unintended consequences.

  • It makes it easier to cascade design-system changes, especially around text and spacing. That is because the utility classes lend themselves to being updatable, like variables, in just one place. Consider the case of spacing: the values are taken from a scale (gl-spacing-0, gl-spacing-10), which means updating from a base of 4px to 6px means updating just those classes but keeping the relations the same.

We've decided to build both component classes and utility classes from the same mixins in order to get these benefits while also having component CSS that can be applied in gitlab-ui and gitlab, Vue and HAML, without undue or repeated effort.

For even more detail on our decision making, RFCs #2 and #4 contain historical discussion around these issues. After RFC #4 was approved, we realized the silent class plus @extend approach generated large amounts of CSS and the approach was modified to use mixins and @include instead. For more context, see also this relevant discussion.

For more information about utility-first CSS, consider a post from Mike Crittenden, Ollie Williams on CSS Tricks or Sarah Dayan's Frontstuff.

Finally, to join in on discussion about HAML components, check out the following ongoing conversations:

So wait, when do I add a variable? a utility class? a component class?

Add a variable (in variables.scss) if you are setting a base value in the design system — this is rare.

Add a component class when writing styles that should apply to both HAML and Vue instances of a component. You may also want to use component classes when you find the same classes are being grouped together for functionality, like .d-flex-center.

Add or apply a utility class the rest of the time.

Other Stylish Questions

More answers and details can be found in the SCSS Styleguide

Contributing guide

Please refer to for details on how to add new components and contribute in general to gitlab-ui.


Any question? Have a look at our, you might find the answer there.




npm i @gitlab/ui

Downloadsweekly downloads









last publish


  • avatar
  • avatar
  • avatar
  • avatar
  • avatar
  • avatar
  • avatar
  • avatar
  • avatar
Report a vulnerability