@snyk-mktg/brand-ui
v3.3.0
Published
The official style library for Snyk's BrandUI Design System
Readme

Snyk BrandUI
Welcome to BrandUI, the official styles library for Snyk's Marketing design system.
Full documentation: https://brand-ui.snyk.marketing/
Usage
Installation
npm i @snyk-mktg/brand-ui
# or
pnpm add @snyk-mktg/brand-uiPre-compiled CSS
Drop a single stylesheet into your app. No Sass compiler needed.
<link rel="stylesheet" href="node_modules/@snyk-mktg/brand-ui/dist/css/bundle.css">Or import from a bundler:
import '@snyk-mktg/brand-ui/dist/css/bundle.css'SCSS Source
Requires a Sass compiler. Import the full bundle or individual layers:
// Full bundle (base tokens + BrandUI theme + components + utilities)
@use '@snyk-mktg/brand-ui/dist/scss/bundle' as *;
// Or pick what you need
@use '@snyk-mktg/brand-ui/dist/scss/base' as *;
@use '@snyk-mktg/brand-ui/dist/scss/components' as *;
@use '@snyk-mktg/brand-ui/dist/scss/utilities' as *;JS / TypeScript Utilities
BrandUI ships helper functions and typed design-token arrays. Both ESM and CommonJS are supported, and full .d.ts declarations are included.
import { buttonVariants, classNames, colors, getInitials, gridSpacing, icons } from '@snyk-mktg/brand-ui'Helpers
| Export | Description |
| ------------------------------------ | ------------------------------------------------------------------------ |
| classNames | Conditionally join class names (similar to the classnames npm package) |
| getInitials | Extract initials from a full name |
| caseFormats | Convert between camelCase, kebab-case, and snake_case |
| gridSpacing, gridSplit | Calculate grid gap and column splits |
| range | Generate a numeric range array |
| uid | Generate a unique identifier string |
| scrollHorizontal, scrollVertical | Programmatic scroll helpers |
| incrementDisplayValue | Animate a counter from 0 to a target value |
Utilities / Types
| Export | Description |
| ---------------------------------------------------------------- | ---------------------------------------- |
| buttonVariants | Array of all button variant names |
| colors | Array of all color token names |
| icons | Array of all icon names |
| logos | Array of all logo names |
| layoutSizes, branduiPadding, branduiSpacing, avatarSizes | Size and spacing scale arrays |
| downloadableFiles | Array of downloadable file type names |
| mediaCategories | Array of media category names |
| patchPoses | Array of Snyk patch character pose names |
All exports include TypeScript type definitions. The package ships both ESM (dist/js/index.js) and CommonJS (dist/js/cjs/index.js) builds.
Available Bundles
| CSS file | SCSS entry point | Contents |
| ----------------- | ------------------ | ------------------------------------------------------- |
| bundle.css | bundle.scss | Base tokens + BrandUI theme + components + utilities |
| evo-bundle.css | evo-bundle.scss | Base tokens + Evo theme + components + utilities |
| labs-bundle.css | labs-bundle.scss | Base tokens + Labs theme + components + utilities |
| base.css | base.scss | Fonts, variables, mixins, resets, typography, layout |
| components.css | components.scss | All UI components (atoms, molecules, organisms) |
| utilities.css | utilities.scss | Utility classes (flex, grid, spacing, visibility, etc.) |
Theming
BrandUI uses a token-driven, two-tier color system. Tier-1 tokens define raw palette values (--color-pink, --color-midnight). Tier-2 tokens are semantic labels (--action, --success, --fail) that each theme maps to different tier-1 values. Components always reference tier-2 labels, so swapping a theme recolors the entire UI without touching component code.
You can use one of the three built-in themes (BrandUI, Evo, Labs) or create your own.
Using a Prebuilt Theme
Import a bundle directly
The simplest approach — just import one of the built-in bundles. Each bundle includes base tokens, a theme, components, and utilities in a single file.
// BrandUI theme (default)
@use '@snyk-mktg/brand-ui/dist/scss/bundle' as *;
// Evo theme
@use '@snyk-mktg/brand-ui/dist/scss/evo-bundle' as *;
// Labs theme
@use '@snyk-mktg/brand-ui/dist/scss/labs-bundle' as *;Or with pre-compiled CSS:
import '@snyk-mktg/brand-ui/dist/css/evo-bundle.css'Generate token files into your project
If you need the token SCSS files in your own directory (e.g. to compose them with your own Sass pipeline), you can generate them:
const { buildAllTokens } = require('@snyk-mktg/brand-ui/build/build-tokens.cjs')
buildAllTokens({
outputDir: './my-app/scss',
themes: ['evo'],
})Then import in SCSS:
@use 'my-app/scss/base/maps/tokens' as base-tokens;
@use 'my-app/scss/evo/base/maps/tokens' as theme-tokens;Creating a Custom Theme
Define your own theme with a single JSON file. The token data can include color-labels, font-family, and/or text-elements — all sections are optional, but at least one of color-labels or text-elements must be present.
Color Labels — Map semantic names to base color keys from tokens/base/colors.json. Values become var(--color-{value}) references.
Font Families — Define named font stacks that text elements reference via {font-family.key} syntax.
Text Elements — Define typography presets. Each text element generates CSS custom properties for size, line-height, weight, family, and letter-spacing. Optional text-transform and responsive.mobile.target fields are also supported.
Minimal Example (color labels only)
{
"color-labels": {
"default": { "$value": "white" },
"action": { "$value": "coral" },
"action-dark": { "$value": "coral" },
"success": { "$value": "mint" },
"fail": { "$value": "rose" }
}
}Full Example (color labels + typography)
{
"color-labels": {
"default": { "$value": "white" },
"action": { "$value": "coral" },
"action-dark": { "$value": "coral" }
},
"font-family": {
"my-sans": { "$value": "Inter, sans-serif", "$type": "fontFamily" }
},
"text-elements": {
"hero-title-large": {
"weight": { "$value": 700 },
"font-size": { "$value": "4rem" },
"line-height": { "$value": "4.5rem" },
"family": { "$value": "{font-family.my-sans}" },
"letter-spacing": { "$value": "-0.01em" },
"responsive": {
"mobile": { "target": "{text-elements.hero-title-small}" }
}
},
"hero-title-small": {
"weight": { "$value": 700 },
"font-size": { "$value": "2.5rem" },
"line-height": { "$value": "3rem" },
"family": { "$value": "{font-family.my-sans}" },
"letter-spacing": { "$value": "-0.01em" }
}
}
}Build the Theme
const { buildCustomTheme } = require('@snyk-mktg/brand-ui/build/build-tokens.cjs')
buildCustomTheme({
tokenFile: './tokens/my-theme.json',
outputDir: './scss',
themeName: 'my-theme',
})This generates ./scss/my-theme/base/maps/_tokens.scss.
You can also pass pre-parsed data instead of a file path:
buildCustomTheme({
tokenData: { 'color-labels': { action: { $value: 'coral' } } },
outputDir: './scss',
themeName: 'my-theme',
})Import in SCSS
// Base tokens from the npm package
@use '@snyk-mktg/brand-ui/dist/scss/base/maps/tokens' as base-tokens;
// Your custom theme
@use './scss/my-theme/base/maps/tokens' as theme-tokens;
// Components and utilities from the npm package
@use '@snyk-mktg/brand-ui/dist/scss/base' as *;
@use '@snyk-mktg/brand-ui/dist/scss/components' as *;
@use '@snyk-mktg/brand-ui/dist/scss/utilities' as *;Text Element Fields Reference
| Field | Required | Example | Notes |
| -------------------------- | -------- | --------------------------------------- | ------------------------------------ |
| weight | Yes | { "$value": 700 } | CSS font-weight |
| font-size | Yes | { "$value": "2rem" } | Any CSS size value |
| line-height | Yes | { "$value": "2.5rem" } | Any CSS size value |
| family | Yes | { "$value": "{font-family.my-sans}" } | Must reference a font-family entry |
| letter-spacing | Yes | { "$value": "-0.01em" } | CSS letter-spacing |
| text-transform | No | { "$value": "uppercase" } | CSS text-transform |
| responsive.mobile.target | No | "{text-elements.hero-title-small}" | Scales down on screens below 768px |
Development
Prerequisites
- Node.js (LTS recommended)
- pnpm 11
Setup
pnpm install
pnpm build:tokens
pnpm buildScripts
| Script | Purpose |
| ------------------- | --------------------------------------------------------------- |
| pnpm build | Full production build (SCSS to CSS + TypeScript to JS via Gulp) |
| pnpm build:tokens | Regenerate _tokens.scss files from JSON token sources |
| pnpm dev:css | Watch SCSS files and recompile on change |
| pnpm compile | TypeScript-only build (emits ESM + CJS to dist/js/) |
| pnpm test | Run the Vitest test suite |
| pnpm lint | Run Biome, Stylelint, and Prettier checks |
| pnpm lint:fix | Auto-fix Biome, Stylelint, and Prettier issues |
| pnpm fmt | Format the repo with Biome and generated SCSS with Prettier |
| pnpm fmt:scss | Format generated SCSS with Prettier |
| pnpm typecheck | Run TypeScript without emitting files |
Local Development
Option 1 — Live Server (isolated SCSS development)
- Install the Live Server VS Code extension.
- Create an
index.htmlat the project root that links todist/css/dev/index.css. - Run
pnpm dev:cssto watch SCSS and recompile on save. - Open the HTML file with Live Server to preview changes in real time.
Option 2 — pnpm link (integration testing)
- Run
pnpm link --globalin this repo to register the package locally. - In your consuming project, run
pnpm link --global @snyk-mktg/brand-ui. - Changes in this repo are immediately reflected in the consuming project.
- When finished, run
pnpm unlink @snyk-mktg/brand-uiin the consuming project andpnpm install --forceto restore the published version.
Architecture
BrandUI uses a token-driven, two-tier design. Design decisions are defined as JSON tokens and compiled into CSS custom properties that every component consumes. Components never reference raw color values directly; they use semantic labels like var(--action) which each theme maps to a different palette color.
Directory Layout
tokens/ Source-of-truth JSON (DTCG format)
base/ Shared across all themes
colors.json Raw color palette (tier 1)
spacing.json Padding, spacing, content-max
effects.json Shadows, radii, transitions
breakpoints.json Device breakpoints
themes/
brandui/ BrandUI theme definitions
color-labels.json Semantic color mappings (tier 2)
typography.json Font families + text elements
evo/ Evo theme definitions
labs/ Labs theme definitions
build/ Token build pipeline (Node.js)
build-tokens.cjs Orchestrator
token-utils.cjs Shared helpers
builders/ One module per token category
dist/
css/ Pre-compiled CSS bundles
scss/ SCSS source (tokens + base + components + utilities)
base/maps/_tokens.scss Generated base CSS vars + Sass lists
{theme}/base/maps/_tokens.scss Generated theme vars
js/ JS/TS utilities (ESM + CJS)Token Flow
tokens/*.json --> pnpm build:tokens --> dist/scss/**/maps/_tokens.scss --> components use var(--*)SCSS Organization
Styles are organized in three layers, with themes applied as a token swap on top:
- Base — Fonts, resets, variables, mixins, layout primitives, typography utilities
- Components — Atomic design hierarchy: atoms (button, input, badge) → molecules (accordion, card, modal) → organisms (hero, navigation, footer)
- Utilities — Single-purpose classes: flex, grid, spacing, visibility, animations, effects, etc.
Each theme (BrandUI, Evo, Labs) loads different _tokens.scss files that reassign CSS custom properties. Evo and Labs also add component-level overrides for elements that need visual changes beyond token swaps (e.g. border-radius, animations).
Token Build System
Running pnpm build:tokens produces four files:
| File | Contents |
| ------------------------------------------ | -------------------------------------------------------------------- |
| dist/scss/base/maps/_tokens.scss | All base CSS vars (:root) + Sass name lists + deprecated Sass maps |
| dist/scss/brandui/base/maps/_tokens.scss | BrandUI color labels + typography |
| dist/scss/evo/base/maps/_tokens.scss | Evo color labels + typography |
| dist/scss/labs/base/maps/_tokens.scss | Labs color labels + typography |
The base file contains tier-1 values (--color-pink, --padding-small, --shadow-medium, etc.) plus Sass name lists ($color-names, $padding-names) used for utility class generation.
Each theme file contains tier-2 semantic mappings (--action: var(--color-pink), --txt-hero-title-large-size: 4rem, etc.) that components reference.
Source Architecture
build/
build-tokens.cjs Orchestrator — buildAllTokens() + buildCustomTheme()
token-utils.cjs Shared helpers (extractTokens, toCssVarLines, readTokenFile, etc.)
builders/
sizing.cjs Padding, spacing, content-max
effects.cjs Shadows, radii, transitions
breakpoints.cjs Device breakpoints
colors.cjs Raw color palette
color-labels.cjs Per-theme semantic color mappings
typography.cjs Per-theme typography + responsive overrides