A quick start guide to add Dialtone to your project.
To take advantage of Dialtone's customizations, classes, and variables in your project, you will want to install Dialtone via npm.
npm install @dialpad/dialtone-css
Add the following line in your Less file:
@import "@dialpad/dialtone-css/lib/build/less/dialtone.less";
If you only need access to Dialtone's variables and customizations to build a file and don't need the whole library exported, use this line instead in your Less file:
@import (reference) "@dialpad/dialtone-css/lib/build/less/dialtone.less";
Dialtone has a four-dimension theming system: mode (light/dark), brand, material (the neutral ramp), and contrast. Add it to your project:
npm install @dialpad/dialtone
import { initDialtoneTheme } from '@dialpad/dialtone/themes/config';
import Dp from '@dialpad/dialtone/themes/dp';
initDialtoneTheme(Dp, 'light');
This gives you runtime switching across all four dimensions, brand-locked materials, high contrast support, and Shadow DOM compatibility for web components.
Learn more about Theme and Mode →
Dialtone's CSS library offers a framework of CSS Utilities classes. Each class is a small, atomic style declaration that, when chained together, should mitigate most situations in which custom CSS must be written. Just write these classes right in your mark-up and you're all set!
<dt-stack
direction="row"
gap="100"
justify="between"
class="
d-w100p
d-bar-400
d-fc-tertiary
d-p-200
d-bgc-moderate
d-ba
d-bc-subtle
"
>
<dt-text as="p" kind="body" :size="200" align="center" tone="tertiary" wrap="balance">
The quick brown fox jumps over the lazy dog.
</dt-text>
<dt-text as="p" kind="body" :size="200" align="center" tone="tertiary" wrap="balance">
The quick brown fox jumps over the lazy dog.
</dt-text>
<dt-text as="p" kind="body" :size="200" align="center" tone="tertiary" wrap="balance">
The quick brown fox jumps over the lazy dog.
</dt-text>
</dt-stack>
In the above example, we used:
<dt-stack> to layout items in a row with consistent gap.<dt-text> for typography with relevant props..d-w100p for full width..d-p-200 to add 16px of padding on all sides..d-bgc-moderate for a moderate background..d-ba for a border on all sides..d-bc-subtle for a subtle border color..d-bar-400 for rounded corners.Though an atomic CSS approach comes with many advantages, we know it also offers a notable disadvantage: reducing the CSS cascade. This is especially true for repeated UI elements, which can end up creating redundant mark-up. For these instances, Dialtone offers components.
There are two methods to implement Dialtone components: Vue (recommended) and CSS. Vue is the preferred method as it's more robust and readily accessible out-of-the-box. Get started with Vue components.
<dt-button>Primary Button</dt-button>
In the event Dialtone Vue doesn't suit your needs, Dialtone's CSS library offers the same set of components in raw HTML and CSS. These may require more work to implement and make accessible, but will work in a pinch.
<button class="d-btn d-btn--primary">Primary Button</button>
In the event you need to write CSS, use BEM (Block Element Modifier). This is a simple, common naming convention that helps make our CSS easier to read and understand. If you aren't familiar with the approach, here's a quick synposis:
.card.card__header.card--featured<div class="card card--featured">
<div class="card__header">...</div>
<div class="card__body">...</div>
<div class="card__footer">...</div>
</div>
.card {
// Local CSS Custom Properties
--card-color-background: var(--dt-color-surface-primary);
// Default block styles
display: flex;
flex-direction: column;
background-color: var(--card-color-background);
border: var(--dt-size-border-100) solid var(--dt-color-border-default);
// Modifier for block
&--featured {
--card-color-background: var(--dt-color-surface-info);
}
// Elements within block
&__header {
padding: var(--dt-spacing-200);
}
&__body {
flex-grow: 1;
padding: var(--dt-spacing-200);
}
&__footer {
padding: var(--dt-spacing-200);
}
}
For internal Dialpad projects, using Dialtone in Backbone should be rare, since most front end changes are now being implemented using Vue. Regardless, if you find yourself needing to use Dialtone in Backbone, there are a few steps:
.less file for your feature, if one does not yet exist..less file into the relevant base less file e.g. single.less, web.less etc..less file and compose your styles like shown in the example above.In order to make Dialtone work across our supported browsers you need to manually install focus-visible polyfill and postcss-focus-visible plugin.
All Dialtone components are implemented with box-sizing: border-box; applied. To understand why we prefer border-box over content-box, please visit this Stack Overflow Teams question.
In Vue, we apply border-box globally at the VueView level, ensuring all child elements use this style. As such, Dialtone styles will work correctly in Vue with respect to element sizing.
In Backbone we are not using border-box by default. Because Dialtone expects this, anytime we wish to use Dialtone styles in Backbone we must ensure to apply the border-box style to all affected elements.
The Dialtone MCP Server enables AI assistants like Claude Code, GitHub Copilot, and Cursor to search Dialtone in real-time while you code. Instead of manually searching documentation, your AI assistant can instantly find the right components, utility classes, design tokens, and icons for you.
Install with npm:
npm install -D @dialpad/dialtone-mcp-server
Create .mcp.json in your project root:
{
"mcpServers": {
"dialtone": {
"command": "dialtone-mcp-server"
}
}
}
Restart your AI assistant to connect. Read the full MCP Server guide for installation options, search tools, and platform-specific setup.
We're excited you want to install Dialtone locally as this most likely means you'll be contributing soon! Before you get to get started though, please make sure you've read our contributing docs.
To run Dialtone locally, you must have Node installed. The required version is specified in .nvmrc at the repo root — use nvm to install and switch to it automatically:
nvm install
nvm use
Once Node is installed, enable Corepack so that the correct pnpm version is used automatically:
corepack enable
Corepack reads the packageManager field in package.json and uses the pinned pnpm version without any manual version switching.
Download the project:
// SSH
git clone git@github.com:dialpad/dialtone.git
// HTTPS
git clone https://github.com/dialpad/dialtone.git
Then cd into the Dialtone directory:
cd ./path/to/dialtone
Dialtone uses Gulp to automate its various workflows. Run the following command to install Gulp and all other project dependencies:
pnpm install
You're now ready to build Dialtone! To build and run the development server:
nx run dialtone-documentation:start
Once finished, visit http://localhost:4000/.
Getting Started documentation last updated Friday, September 4, 2026
fix/popover-modal-zindex-scope