Design system

Drawstrings

A minimal, framework agnostic UI component library based on GitLab's Pajamas design

A minimal, framework-agnostic UI component library based on GitLab's Pajamas design system, built on Web Components (Lit). It also ships a Slippers (GitLab marketing) theme you can switch to at runtime.

Because the components are standard custom elements, they work anywhere HTML does — vanilla JS, Vue, React, Svelte, etc. — with no framework dependency.

Installation

Drawstrings is published to its GitLab project package registry. Point npm at that registry, then install.

Add to your project's .npmrc (replace <project_id> with the numeric ID shown on the project's overview page, and provide a token with read_package_registry scope):

registry=https://gitlab.com/api/v4/projects/<project_id>/packages/npm/
//gitlab.com/api/v4/projects/<project_id>/packages/npm/:_authToken=${GITLAB_TOKEN}
npm install drawstrings
Quick start

Import the package to register every gl-* custom element, and import the stylesheet to load the design tokens and themes:

import 'drawstrings' // registers the gl-* elements
import 'drawstrings/styles' // → drawstrings.css (design tokens + Pajamas/Slippers themes)
<gl-button variant="confirm">Save</gl-button>
<gl-badge variant="success">Passed</gl-badge>
<gl-alert variant="info" title="Heads up">Pipeline finished.</gl-alert>

Each component's own styling lives in Shadow DOM, so the elements render even without the stylesheet — but drawstrings/styles provides the canonical token values and is required for theming (the Slippers theme and any --gl-* overrides live there). The CSS is a separate artifact, so importing only the JS will not pull it in.

Browser / CDN (no build step)

The IIFE build exposes a global Drawstrings and self-registers the elements:

<link rel="stylesheet" href="drawstrings/dist/drawstrings.css" />
<script src="drawstrings/dist/drawstrings.min.js"></script>
<gl-button variant="confirm">Save</gl-button>
Framework usage

The elements are framework-agnostic. Two notes:

  • Vue 3 — tell the compiler that gl-* tags are custom elements so it doesn't try to resolve them as Vue components:

    // vite.config.js
    vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('gl-') } } })
    
  • React — attributes (strings/booleans) work directly. For rich properties (arrays/objects like gl-select's options), set them via a ref, or use React 19's improved custom-element property handling.

Theming (Pajamas ↔ Slippers)

Pajamas is the default. Switching to Slippers is a pure token swap — no re-render, no per-component config. Set data-design-system on the document root, or use the helper:

import { setDesignSystem, getDesignSystem } from 'drawstrings'

setDesignSystem('slippers') // or 'pajamas' (default)
getDesignSystem() // → 'slippers'

Equivalently, in markup:

<html data-design-system="slippers">
  …
</html>

The attribute cascades to every component (custom properties inherit through Shadow DOM), so a single toggle re-skins the whole page.

Customizing tokens

All styling flows through --gl-* CSS custom properties. Override them at :root (or any scope) to tune the look without forking components:

:root {
  /* Brand the primary action */
  --gl-button-confirm-bg: #7759c2;
  /* Or remap the palette wholesale */
  --gl-color-blue-500: #1a73e8;
}

Component-specific tokens (e.g. --gl-button-confirm-bg, --gl-link-color) fall back to the semantic color scale (--gl-color-blue-500, …), which falls back to a literal default — so you can override at whichever level you need.

Icons

<gl-icon> renders from a built-in registry of Pajamas icons:

<gl-icon name="check" size="16" label="Done"></gl-icon>
  • Custom icons / sprites: add to the registry with registerIcon(name, svg, viewBox?), or point at a GitLab SVG sprite with setSpriteUrl(url).

  • Slippers marketing icons are large and shipped as an opt-in entry that registers them under slp-* names:

    import 'drawstrings/slippers-icons'
    
    <gl-icon name="slp-announce-release" size="32"></gl-icon>
    
Development
npm run dev        # Vite dev server + demo page (index.html)
npm run build      # build dist/ (ESM, CJS, IIFE, CSS, types)
npm run typecheck  # tsc --noEmit
npm run test:e2e   # Playwright smoke tests against the demo page

The demo page includes a Pajamas/Slippers switcher to preview both themes.

Component demos

Button

Default Confirm Danger Dashed Disabled Link

Badge

Neutral Muted Info Success Warning Danger 42

Avatar

Alert

Something you should know. Your changes were saved. Something went wrong.
Retry

Label

Select

Form Group

Input

Checkbox

Icon

Accordion

GitLab is a complete DevSecOps platform delivered as a single application. Sign up at gitlab.com, create a project, and push your first commit. GitLab Community Edition is open source under the MIT license. This content is inaccessible.

Avatar Group

Button Group

Day Week Month Merge

Card

This project contains the source code for the GitLab web interface.

View details
New Pipeline results

3 of 4 jobs passed. See the full report for details.

Banner

Unlock advanced security scanning, compliance pipelines, and more.
Upgrade now Learn more
AI-powered features are now available across your organization.
Try GitLab Duo

Link

Default link Subtle link Danger link External link

Segmented Control

Token

Truncate

Skeleton

Stepper

← Prev Next →

Drawer

Open right drawer Open left drawer
Cancel Save

Left-side navigation drawer.

Close

Popover

Show info

3 of 4 jobs passed. The test:unit job failed.

No title This popover has no title — just body content. Top Appears above the trigger.

Textarea

Pagination

Toast

Info toast Success toast Warning toast Danger toast Persistent toast

Toggle

Radio

Spinner

Progress

Breadcrumb

GitLab gitlab-org gitlab Issues

Tooltip

Copy Open Delete

Tabs

This is the Overview tab panel.

Recent activity will appear here.

Releases content.

Configure your project settings.

Modal

Open small Open medium Open large

This pipeline and all of its jobs will be permanently deleted. This action cannot be undone.

Cancel Delete pipeline
Cancel Save changes

Large modal content goes here. Useful for forms with many fields or wider content like tables.

Cancel Apply

Dropdown

Edit Duplicate Delete Approve MR Merge Rebase and merge Never shown Profile Settings Sign out
View profile Settings Sign out

Empty State

New merge request Learn more

Search Input

Character Count

Table

Combobox

Date Picker

Collapse

Toggle details
Collapse is a low-level show/hide primitive. Unlike accordion it has no built-in chrome — supply your own trigger and content.
Expanded by default
This panel starts open because the visible attribute is set.

Tree

Path

Attribute List

Active Private April 16, 2026 Mike Leopard 12345678 main

Animated Number

Pipelines run
Coverage
Randomize

Broadcast Message

GitLab will undergo scheduled maintenance on Saturday at 02:00 UTC. Learn more A new version of GitLab is available for your self-managed instance. Your subscription has been renewed successfully.

Input Group

https:// .git

Typography

Display Heading 1 Heading 3 Heading 5 Body 1 — lead paragraph text. Body 2 bold All caps label

Grid

span 6
span 6
12 / md 4
12 / md 4
12 / md 4

Section & Side Nav

In a section band The section paints a full-width background; the grid lays out the nav and content.