# @dialpad/dialtone-tokens

> Design tokens for Dialtone.

Latest version **2.0.2** (published 2026-09-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install @dialpad/dialtone-tokens
pnpm add @dialpad/dialtone-tokens
yarn add @dialpad/dialtone-tokens
bun add @dialpad/dialtone-tokens
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types; large bundle.

## Facts

| | |
|---|---|
| Version | 2.0.2 |
| Published | 2026-09-22 |
| First published | 2022-08-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Dependencies | 0 |
| Unpacked size | 156.8 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| Maintainers | braddialpad, jadialpad, jawrey, juliodialpad |

## Links

- npm: https://www.npmjs.com/package/@dialpad/dialtone-tokens
- Repository: https://github.com/dialpad/dialtone
- Homepage: https://dialtone.dialpad.com/
- Issues: https://github.com/dialpad/dialtone-tokens/issues
- npm.io page: https://npm.io/package/@dialpad/dialtone-tokens

## Recent versions

- 2.0.2 (latest) — 2026-09-22
- 2.0.0-next.8 (next) — 2026-08-27
- 1.47.1-beta.1 (beta) — 2025-09-29
- 1.42.0-rebrand-2025-beta.3 (rebrand-2025-beta) — 2025-04-07
- 1.28.0-alpha.1 (alpha) — 2024-04-03
- 2.0.1 — 2026-09-18
- 2.0.0 — 2026-09-16
- 1.49.0 — 2026-09-16
- 1.48.0 — 2026-09-16
- 2.0.0-next.7 — 2026-08-18
- 2.0.0-next.6 — 2026-07-23
- 2.0.0-next.5 — 2026-07-22
- 2.0.0-next.4 — 2026-07-15
- 2.0.0-next.3 — 2026-07-15
- 2.0.0-next.2 — 2026-07-13
- … 131 more at https://npm.io/package/@dialpad/dialtone-tokens/versions

## README

# Dialtone

The monorepo for Dialpad's design system Dialtone.

> **Dialtone v10:** see [DLT-2979](https://dialpad.atlassian.net/browse/DLT-2979) / [#1426](https://github.com/dialpad/dialtone/pull/1426) for the v10 upgrade and its breaking changes. This is a MAJOR version release.

All separate packages of dialtone are also deployed individually.
If you would like to use an individual package rather than the combined Dialtone package,
you can find documentation for each package in the following table.

## Usage

The below usage instructions are for the combined package.

### Install it via NPM:

```shell
npm install @dialpad/dialtone @dialpad/i18n
```

---

### Import CSS

```js
import '@dialpad/dialtone/css';
```

#### No-Layers Build

If your project cannot use CSS Cascade Layers, import the no-layers variant. You will likely need to use the no-layers build if you are upgrading from Dialtone <=9, unless you migrate your application CSS to support layers. See the [CSS Cascade Layers migration guide](https://dialtone.dialpad.com/guides/migration/css-cascade-layers/) for more details.

```js
import '@dialpad/dialtone/css/no-layers';
```

---

### Theming

Dialtone has four theming dimensions: **mode** (light/dark), **brand** (the color palette), **material** (the neutral ramp), and **contrast** (default/high). Each switches at runtime via `@dialpad/dialtone/themes/config`. See the [Theme and Mode guide](https://dialtone.dialpad.com/guides/theme-and-mode/) for the full API.

#### Quick Start

**Install:**

```shell
npm install @dialpad/dialtone
```

**Initialize (main.js or App.vue):**

```js
import { initDialtoneTheme } from '@dialpad/dialtone/themes/config';
import Dp from '@dialpad/dialtone/themes/dp';

initDialtoneTheme(Dp, 'light');
```

Done. Your app now has theming.

---

##### Basic Usage

```js
import {
  setMode,
  setBrand,
  setMaterial,
  setContrast,
} from '@dialpad/dialtone/themes/config';
import Tmo from '@dialpad/dialtone/themes/tmo';
import HighContrast from '@dialpad/dialtone/themes/high-contrast';

setMode('dark');           // toggles data-dt-mode, no injection
setBrand(Tmo);             // injects brand CSS, sets data-dt-brand
setMaterial('steel');      // injects material CSS, sets data-dt-material
setContrast(HighContrast); // injects contrast CSS, sets data-dt-contrast
setContrast(null);         // remove contrast override
```

`setMode` toggles an attribute against pre-bundled CSS — no injection. `setBrand`, `setMaterial`, and `setContrast` inject per-theme override CSS.

---

##### Brand-locked materials

Most brands declare a paired material via the `shell.base.material` token in their token JSON. `setBrand` auto-applies the locked material in the same paint frame. Free-choice brands (`dp`, `tmo`, `prota-deuter`, `trita`) keep material independent.

```js
import { getBrandMaterial, hasBrandMaterialLock } from '@dialpad/dialtone/themes/config';
import Botany from '@dialpad/dialtone/themes/botany';

getBrandMaterial(Botany);     // 'sandstone'
hasBrandMaterialLock(Botany); // true
```

Use these getters to drive picker UI (disable material options on locked brands).

---

##### Available Themes

50 themes total. Pass theme modules to `initDialtoneTheme()` or `setBrand()`.

**Base:** dp (Dialpad — every other theme layers on top of it) · **Partner:** tmo

**Standard:** aegean, alpine, arctic, aurora, autumn, blue-hour, botany, brick, buttercream, cactus-bloom, cayenne, cedar-grove, cobalt, copper, coral-reef, dragonfruit, eucalyptus, fjord, high-desert, inkberry, kiln, lavender, marigold, melon, mulberry, mushroom, nightshade, paprika, peach-blossom, plum, poppy-field, raincloud, rhubarb, rust-harbor, sea-glow, seashell, solstice, storm, sunflower, tropical-night, verdant-haze, wildflower, wineberry, winter-gold, woodland

**Accessibility:** prota-deuter, trita

**Contrast:** high-contrast

**Materials** (string names, no module imports): sandstone, steel, graphite, iron, amethyst, jade

```js
import ThemeName from '@dialpad/dialtone/themes/theme-name';
```

---

##### Advanced

**Shadow DOM (Web Components):**

Pass host element as third parameter.

```js
initDialtoneTheme(Dp, 'light', this);
```

**CSS only (no JS):**

```css
@import "@dialpad/dialtone-tokens/layered/tokens-core.css";
@import "@dialpad/dialtone-tokens/layered/tokens-base-colors.css";
@import "@dialpad/dialtone-tokens/layered/tokens-dp-colors.css";
```

Then set attributes:

```html
<html data-dt-mode="light" data-dt-brand="dp" data-dt-material="sandstone" data-dt-contrast="default">
```

**Mode sections:**

See [Mode Island component](https://dialtone.dialpad.com/components/mode-island.html) docs.

---

##### Legacy Theming System (Backward Compatible)

The original `setTheme()` API remains supported for existing projects. New projects should use the layered system above for smaller bundle sizes and finer-grained switching across all four dimensions.

```js
import { setTheme } from '@dialpad/dialtone/themes/config';
import DpLight from '@dialpad/dialtone/themes/dp-light';
import DpDark from '@dialpad/dialtone/themes/dp-dark';

setTheme(DpLight);   // auto-detected as legacy
setTheme(DpLight, document.querySelector('#my-shadow-root-host')); // Shadow DOM support
```

**Legacy themes:** `DpLight`, `DpDark`, `TmoLight`, `TmoDark` — each ships the complete token set (~1256KB per theme), versus the layered system's small per-dimension overrides.

#### Dialtone icons

```js
// Named import
import { DtIconArrowUp } from '@dialpad/dialtone-icons/vue';
import { DtIllustrationBlankSpace } from '@dialpad/dialtone-icons/vue';

// Default import (Preferred if using webpack as it is tree-shakeable by default)
import DtIconArrowUp from '@dialpad/dialtone-icons/vue/arrow-up';
import DtIllustrationBlankSpace from '@dialpad/dialtone-icons/vue/blank-space';
```

#### Dialtone Vue components

```js
// Named import
import { DtButton } from "@dialpad/dialtone/vue"

// Default import (Preferred if using webpack as it is tree-shakeable by default)
import { DtButton } from "@dialpad/dialtone/vue/lib/button"
```

> **Note:** Dialtone Vue 2 has been deprecated. Please migrate to Dialtone Vue. The latest version of Dialtone that still supports Vue 2 is 9.154.0.

#### Dialtone MCP Server

Install the MCP server to use it in your local environment and develop efficiently with Dialtone.
Follow the instructions in the [MCP Server](https://github.com/dialpad/dialtone/tree/staging/packages/dialtone-mcp-server) folder.

## About this repo

The @dialpad/dialtone repository is a monorepo composed of Dialtone NPM packages and apps.

The following is a list of packages included in this monorepo. Note that libraries (packages folder) are separated from
apps (apps folder):

```text
dialtone/
|--- .github                            # Github configuration and workflows
|--- apps                               # Buildable and deployable applications
  |--- dialtone-documentation           # Documentation site
|--- common                             # Common files shared between packages
|--- generator-dialtone                 # Yeoman Generator for creating new packages
|--- packages                           # Libraries that are being developed within the monorepo and published to NPM/GitHub
  |--- combinator                       # Combinator component
  |--- dialtone-css                     # CSS library
  |--- dialtone-emojis                  # Emoji assets
  |--- dialtone-icons                   # SVG and Vue icons library compatible with vue@2 and vue@3
  |--- dialtone-mcp-server              # MCP Server
  |--- dialtone-tokens                  # CSS Tokens library
  |--- dialtone-vue                    # Vue component library compatible with vue@3
  |--- eslint-plugin-dialtone           # Custom ESLint rules for Dialtone users
  |--- language-server                  # Language tools based on Volar Framework
  |--- postcss-responsive-variations    # PostCSS plugin to generate responsive classes
  |--- stylelint-plugin-dialtone        # Custom Stylelint rules for Dialtone users
|--- scripts                            # Shared scripts
```

### Dialtone mono-package

Dialtone is a mono-package that includes many packages within it to ease the maintenance of versions of
the library.

#### How our bundling works

To achieve this we needed to create certain configs through the monorepo to be able to handle them even if
they have the same package name e.g: `@dialpad/dialtone-vue`.

1. In root [package.json](package.json):
   - `pnpm`:
     - `peerDependencyRules` include `vue": "^3.2"` to make sure we don't have warnings related to vue version
       mismatch.
     - `packageExtensions` tells pnpm which Vue version to use for each package.
2. On individual packages `package.json` files:
   - Include the specific dependencies in case someone uses the individual package
   - In `vite.config.js` [Vue 3](packages/dialtone-vue/vite.config.js) add dependencies to external to make sure they don't cause issues on product.
3. In [project.json](project.json)
   - Include implicit dependencies to make sure NX builds them before trying to copy the files to the mono-package.
4. In `gulpfile.cjs`
   - Copy the built files into the root `dist` folder.

#### Included packages

- Dialtone CSS
- Dialtone Tokens
- Dialtone Vue

### Tree-shaking

Tree-shaking is a feature that allows you to remove unused code from your bundle, and it is enabled by default in our
build process for Dialtone, Dialtone Vue, Dialtone Combinator and Dialtone Icons.

We achieve tree-shaking primarily via three mechanisms across the packages:

#### Marking packages as side effect free

`sideEffects: false` is set so bundlers can drop unused imports.

- `@dialpad/dialtone` → [package.json](package.json) line 242
- `@dialpad/dialtone-vue` (vue3) → [package.json](packages/dialtone-vue/package.json) line 145
- `@dialpad/dialtone-combinator` → [package.json](packages/combinator/package.json) line 56
- `@dialpad/dialtone-icons` → [package.json](packages/dialtone-icons/package.json) line 98

#### Publishing ESM builds (with dual ESM/CJS via exports map)

Packages expose ESM for bundlers to statically analyze and tree-shake, with CJS fallbacks.

- `@dialpad/dialtone-vue` (vue3):
  - `"type"`: `"module"`,
  - `"module"`: `"./dist/dialtone-vue.js"`,
  - `"main"`: `"./dist/dialtone-vue.cjs"`,

#### Deep, per-module entry points to enable fine-grained import paths

Exports maps expose subpath entries so consumers can import only what they need (which aids tree-shaking and avoids
pulling entire bundles):

- `@dialpad/dialtone` exposes `./vue/lib/*` map to individual component imports.
- `@dialpad/dialtone-vue` exposes `./lib/*` for individual component imports.
- `@dialpad/dialtone-icons` exposes `./vue3/*` for individual icon/illustration imports.

### Available packages

| Name                                                             | Description                                                                                                                                        | Version                                                                                                   |
|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|
| [Dialtone](README.md)                                            | Combined package containing the latest versions of the libraries for ease of use                                                                   | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fdialtone?logo=npm&color=7C52FF)                  |
| [Dialtone CSS](packages/dialtone-css/README.md)                  | Classes or styles used within Dialtone should be stored here and documented on our site under `apps/dialtone-documentation`                        | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fdialtone-css?logo=npm&color=7C52FF)              |
| [Dialtone emojis](packages/dialtone-emojis/README.md)            | Emoji assets                                                                                                                                       | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fdialtone-emojis?logo=npm&color=7C52FF)           |
| [Dialtone icons](packages/dialtone-icons/README.md)              | Resources needed to implement icons on your application that conform to Dialpad’s design principles and best practices                             | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fdialtone-icons?logo=npm&color=7C52FF)            |
| [Dialtone tokens](packages/dialtone-tokens/README.md)            | Design tokens for Dialpad's design system Dialtone and everything related to building and publishing them                                          | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fdialtone-tokens?logo=npm&color=7C52FF)           |
| [Dialtone Vue](packages/dialtone-vue/README.md)                  | Vue components library to simplify and standardize the use of common UI patterns and behaviour across all Dialpad projects                         | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fdialtone-vue?logo=npm&color=7C52FF)              |
| [ESlint plugin](packages/eslint-plugin-dialtone/README.md)       | ESLint plugin containing rules to help developers maintain dialtone recommended practices                                                          | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Feslint-plugin-dialtone?logo=npm&color=7C52FF)    |
| [Stylelint plugin](packages/stylelint-plugin-dialtone/README.md) | StyleLint plugin containing rules to help developers maintain dialtone recommended practices for CSS                                               | ![NPM Version](https://img.shields.io/npm/v/%40dialpad%2Fstylelint-plugin-dialtone?logo=npm&color=7C52FF) |

## Contributing

Please read our [contributing guide](.github/CONTRIBUTING.md) **before submitting a pull request**.

### Quick start

If you would like to contribute to Dialtone without having to do any local environment setup, you can use GitHub
Codespaces. You can initialize a new Codespace by clicking the green "Code" button at the top right of the Dialtone
GitHub page.

![Creating a codespace](./.github/new_codespace.png)

Please see the [Codespaces docs](./.github/codespaces.md) for more information.

### Local development

#### PNPM

PNPM (Performant NPM) is a package management solution designed to address the challenges posed by
traditional package managers.

We use PNPM to manage everything related to NPM, **adding, installing, removing and publishing packages**.

You will need to install PNPM locally to contribute to this project. <https://pnpm.io/installation>

The repo pins an exact pnpm version via the `packageManager` field in `package.json`. The recommended way to automatically use the correct version per repo is [Corepack](https://nodejs.org/api/corepack.html), which ships with Node.js:

##### Installation

```bash
corepack enable
```

Corepack reads the `packageManager` field and transparently uses the pinned pnpm version — no manual version switching needed across repos.

##### Do

Use PNPM to manage package dependencies

```bash
pnpm add eslint --filter dialtone-icons
```

##### Don't

Run package scripts with PNPM, this will not use NX cache and pipelines,
so you might end up missing dependencies that needed to be built before.

```bash
pnpm run --filter dialtone-css build
```

#### NX

Nx is a build system with built-in tooling and advanced CI capabilities.
It helps you maintain and scale monorepos, both locally and on CI.

NX manages the scheduling and caching of our PNPM scripts.

We still rely on the package installation and package linking mechanism that PNPM workspaces provide us,
but use Nx instead to **run our tasks in the most efficient way**.

One of the main benefits of adding Nx to our PNPM workspace is speed via caching.

Running commands via NX will enable us to do several things:

- Set up the project dependencies to other projects command,
if they need to run before a specific command.
- Improve the speed of the command execution by saving its output to cache.
- Run the command on the [affected](https://nx.dev/nx-api/nx/documents/affected) projects only.

⚠️ You can run the commands with PNPM too, but it's not advisable as you'll lose the advantages that NX provides.

For more information, check [setup a monorepo with PNPM workspaces and NX](https://nx.dev/blog/setup-a-monorepo-with-pnpm-workspaces-and-speed-it-up-with-nx)

##### Installation

It is recommended to install NX globally via:

```bash
pnpm add --global nx@latest
```

##### Do

Use NX to run scripts, this will use cache, improve the performance,
and build any dependency needed before running your command.

```bash
nx run dialtone-css:build
```

##### Don't

Try installing packages with NX, this doesn't work at all, please use PNPM instead.

```bash
nx add eslint --filter dialtone-icons
```

#### Running the projects

First, install the dependencies for all the monorepo packages and apps.

```bash
pnpm install
```

##### Dialtone documentation site

```bash
nx run dialtone-documentation:start
```

This will start the documentation site and watch the library for changes, it will be live updated with any changes.

Access the local server at `http://localhost:4000`

##### Dialtone Vue storybook

```bash
nx run dialtone-vue:start
```

Access the local storybook server for Dialtone Vue via `http://localhost:9011/`

#### Common Commands

##### Production build the root project

```bash
nx run dialtone:build
```

Use the `--filter` flag to run commands for a specific package or app.

##### Adding dependencies for individual packages

```bash
pnpm add <dependency> --filter <package or app name>
```

Example:

```bash
pnpm add eslint --filter dialtone-icons
```

To install a local dependency, just add the `--workspace` flag

```bash
pnpm add <dependency> --filter <package or app name> --workspace
```

Example:

```bash
pnpm add @dialpad/dialtone-tokens --filter dialtone-icons --workspace
```

##### Running commands for individual packages

You can run commands like `build`, `test`, `start` for individual packages from
the root of the project using:

```bash
nx run <package/app>:<target>
```

Example:

```bash
nx run dialtone-documentation:build
```

##### Clean build artifacts and cache

Use this to clear stale build artifacts and reset the build cache. Common scenarios include switching branches, troubleshooting unexpected build behavior, or recovering from interrupted builds. This is rarely needed because build scripts already clean their own dist folders and Nx cache invalidation handles most staleness automatically.

```bash
# Clean everything (dist folders and Nx cache)
pnpm clean

# Clean only dist folders (stale build artifacts)
pnpm clean:dist

# Clean only Nx cache (confused incremental builds)
pnpm clean:cache
```

What gets cleaned:

- `clean:dist` removes `packages/dialtone-tokens/dist` and VuePress cache/temp directories
- `clean:cache` clears Nx's build cache (`.nx/cache`)
- `clean` runs both in sequence

##### Use local package in another project

A way to see local Dialtone changes in a local running frontend is to use a local package.

To create a Dialtone package, first run (in Dialtone repo):

```bash
pnpm pack
```

This will generate a `.tgz` file, with the same format as the one published on npm. To use this package on another project you can run:

```bash
npm install <path to previously generated tgz file>
npm run dev
```

### Releasing

Currently, Dialtone packages are being released in two different ways: `scheduled` and `manually`.
The `scheduled` release will only release changes to `production` while `manually` you can choose to release
`alpha` or `beta` branches.

#### Production

##### Scheduled

On every Tuesday at 10:00 am UTC, [release action](.github/workflows/release.yml) will trigger the production release process which
automatically release all packages that need to be released following the next steps:

1. Run the `release` target on every project.
2. Merge the release commits created by the semantic release bot on `staging` to `production` branch.
3. Push the `production` branch.
4. The [publish action](https://github.com/dialpad/dialtone/actions/workflows/publish.yml) will publish the packages with its corresponding tag.

##### Manually

In case you need to release earlier than the next scheduled date, you can trigger the release via `Run workflow` on [GitHub](https://github.com/dialpad/dialtone/actions/workflows/release.yml).

  1. Select `staging` branch.
  2. Select the `package` that you want to release or leave it empty to release all of them.

This will trigger the [release action](.github/workflows/release.yml), release changes on `staging` and automatically publish the selected packages following the next steps:

1. Run the `release` target on selected packages (all if `package` is empty).
2. Merge the release commits created by the semantic release bot on `staging` to `production` branch.
3. Push the `production` branch.
4. The [publish action](https://github.com/dialpad/dialtone/actions/workflows/publish.yml) will publish the packages with its corresponding tag.

#### Alpha/Beta

1. Merge your changes to the branch you want to release, commit and push to origin. (Note: If your dialtone version number is behind the last production release number, it may fail. Merge in staging or update the version number manually.)
2. Go to [GitHub](https://github.com/dialpad/dialtone/actions/workflows/release.yml) and click on `Run workflow`.
3. Select `alpha` or `beta` branch.
4. Select the `package` that you want to release or leave it empty to release all of them.

This will trigger the [release action](.github/workflows/release.yml), release changes on the selected branch and automatically publish the selected packages following the next steps:

1. Run the `release` target on selected packages (all if `package` is empty).
2. The [publish action](https://github.com/dialpad/dialtone/actions/workflows/publish.yml) will publish the packages with its corresponding tag.

### Testing

#### Run Vue tests

```bash
nx run dialtone-vue:test
```

#### Run Vue unit tests with coverage

```bash
nx run dialtone-vue:test:coverage
```

These will generate a JSON and HTML report in the `coverage` directory.

#### Test Coverage thresholds

The coverage thresholds are defined in the `vitest.config.ts` file.
When submitting a PR the CI will run the tests with coverage and fail if the coverage is below the thresholds.

<!-- test -->

---
_Source: https://npm.io/package/@dialpad/dialtone-tokens · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
