The tokens.config.ts file is the central piece of your styling API.

This is the place where you must structure and store all your Design tokens.

Even though it looks like a plain key/value object, defineTheme() content is a living object that provides all the tooling needed for you to create a clean and maintainable theming definition.

If you want to combine two or more tokens configurations, take a look at the Multi layer page.

Your first theme

You can start creating your own theme simply by adding a tokens.config.ts file at the root of your project, here is a sample for it:

import { defineTheme } from 'pinceau'
export default defineTheme({
media: {
tablet: '(min-width: 768px)',
desktop: '(min-width: 1024px)',
color: {
white: '#FFFFFF',
black: '#191919',
primary: '#ED4D31',
secondary: '#4560B0',
tertiary: '#FBEFDE'
space: {
1: '0.25rem',
2: '0.5rem',
3: '0.75rem',
4: '1rem'
.css output
@media {
:root {
--pinceau-mq: initial;
--space-4: 1rem;
--space-3: 0.75rem;
--space-2: 0.5rem;
--space-1: 0.25rem;
--color-tertiary: #FBEFDE;
--color-secondary: #4560B0;
--color-primary: #ED4D31;
--color-black: #191919;
--color-white: #FFFFFF;
--media-desktop: (min-width: 1024px);
--media-tablet: (min-width: 768px);
.ts output
export const theme = {
"media": {
"tablet": {
"value": "(min-width: 768px)",
"variable": "var(--media-tablet)",
"original": "(min-width: 768px)"
"desktop": {
"value": "(min-width: 1024px)",
"variable": "var(--media-desktop)",
"original": "(min-width: 1024px)"
"color": {
"white": {
"value": "#FFFFFF",
"variable": "var(--color-white)",
"original": "#FFFFFF"
"black": {
"value": "#191919",
"variable": "var(--color-black)",
"original": "#191919"
"primary": {
"value": "#ED4D31",
"variable": "var(--color-primary)",
"original": "#ED4D31"
"secondary": {
"value": "#4560B0",
"variable": "var(--color-secondary)",
"original": "#4560B0"
"tertiary": {
"value": "#FBEFDE",
"variable": "var(--color-tertiary)",
"original": "#FBEFDE"
"space": {
"1": {
"value": "0.25rem",
"variable": "var(--space-1)",
"original": "0.25rem"
"2": {
"value": "0.5rem",
"variable": "var(--space-2)",
"original": "0.5rem"
"3": {
"value": "0.75rem",
"variable": "var(--space-3)",
"original": "0.75rem"
"4": {
"value": "1rem",
"variable": "var(--space-4)",
"original": "1rem"
} as const
export type GeneratedPinceauTheme = typeof theme
export type GeneratedPinceauPaths = "media.tablet" | "media.desktop" | "color.white" | "" | "color.primary" | "color.secondary" | "color.tertiary" | "space.1" | "space.2" | "space.3" | "space.4";
export default theme

In addition to these outputs, Pinceau also creates:

  • utils.ts that is used to expose your Utils Properties anywhere you need it
  • definitions.ts that is used by the VSCode extension
  • schema.ts that will be used by Nuxt Studio to provide a GUI over all your tokens configuration

Tokens references

Inside your configuration, you can use references to already defined tokens.

Let's create a primary color from another color in our configuration.

primary: '{}',
blue: {
50: '#C5CDE8',
100: '#B6C1E2',
200: '#99A8D7',
300: '#7B8FCB',
400: '#5E77C0',
500: '#4560B0',
600: '#354A88',
700: '#25345F',
800: '#161E37',
900: '#06080F',

The $dt('color.primary') or '{color.primary}' references will point to var(--color-blue-500).

This is useful when creating some global tokens in your themes that will be overwritten at multiple levels.

Configuration structure

If you have no configuration generated, defineTheme typing will suggest you a structure for your tokens.

Once you start adding some tokens, your scaffolding will become the typing.

You are free to follow the suggestion, or to organize your tokens using any naming you like.

There is only two reserved keys in the configuration:

defineTheme typing

The defineTheme function is not only a type-helper!

Its typing will be based on a merged version of all your theming layers.

That gives you an autocompletable object that references all the actual tokens from your project.