Skip to content

Tailwind CSS Integration ​

Generate a Tailwind CSS preset from your design tokens.

Setup ​

TIP

Make sure you have the Cobalt CLI installed!

Install the plugin from npm

sh
npm i -D @cobalt-ui/plugin-tailwind

Then add to your tokens.config.mjs file, configuring theme as you would normally, except replacing the values with token IDs:

js
import pluginTailwind from "@cobalt-ui/plugin-tailwind";

/** @type {import("@cobalt-ui/core").Config} */
export default {
  plugins: [
    pluginTailwind({
      /** (optional) the path to the Tailwind preset */
      output?: "./tailwind-tokens.js",
      /** (optional) module format to use (to match your Tailwind config) */
      outputFormat?: "esm" | "cjs",
      tailwind: {
        theme: {
          /** @see https://tailwindcss.com/docs/configuration#theme */
          colors: {
            blue: {
              100: "color.blue.100",
              200: "color.blue.200",
              // …
            },
          },
          fontFamily: {
            sans: "typography.family.base",
            // …
          },
          extend: {
            spacing: {
              1: "token.size.s.space",
              2: "token.size.m.space",
              // …
            },
            borderRadius: {
              m: "token.size.m.borderRadius",
              // …
            },
          },
        },
      },
    }),
  ],
};

Then run:

sh
npx co build

And you’ll generate a ./tokens/tailwind-tokens.js file. Add it to your Tailwind config presets and your Tailwind theme now pulls directly from your design tokens:

js
import tailwindTokens from "./tokens/tailwind-tokens.js"; 

/** @type {import("tailwindcss").Config} */
export default {
  presets: [  
    tailwindTokens, 
  ], 
};

TIP

Be sure to rerun co build to rebuild your Tailwind preset, or run co build --watch to rebuild your tokens every time they change!

Automated mapping ​

Because the Tailwind config is “just JS,” you can automate the mapping by using JS:

js
import pluginTailwind from "@cobalt-ui/plugin-tailwind";

function makeColor(colorName) {
  const output = {};
  for (const step of [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]) {
    output[step] = [colorName, step].join("."); // e.g. `color.blue.50`
  }
  return output;
}

/** @type {import("@cobalt-ui/core").Config} */
export default {
  tokens: "./tokens.json",
  outDir: "./tokens/",
  plugins: [
    pluginTailwind({
      tailwind: {
        theme: {
          colors: {
            blue: makeColor("color.blue"), // { 50: "color.blue.50", 100: "color.blue.100", … }
            green: makeColor("color.green"), // { 50: "color.green.50", 100: "color.green.100", … }
            // …
          },
        },
      },
    }),
  ],
};

Use this to avoid having to repeat yourself when mapping between dozens (if not hundreds) of your tokens.

CommonJS ​

If you’re still using CommonJS (using require("…") rather than import "…"), make sure to change the outputFormat setting to cjs:

js
import pluginTailwind from "@cobalt-ui/plugin-tailwind";

/** @type {import("@cobalt-ui/core").Config} */
export default {
  plugins: [
    pluginTailwind({
      outputFormat: "cjs",
    }),
  ],
};

Using CSS Variables ​

Because Tailwind lets you use any CSS variables from anywhere, you can use @cobalt-ui/plugin-css to generate these for you. However, you might be using some advanced functionality such as <alpha-value> that requires specific color formats. In those cases, you can use plugin-css’ transform() option in combination with the fast, accurate, and lightweight culori library to format colors in the desired format:

sh
npm i -D @cobalt-ui/plugin-css culori
js
import pluginCSS from "@cobalt-ui/plugin-css";
import pluginTailwind from "@cobalt-ui/plugin-tailwind";
import * as culori from "culori";

/** @type {import("@cobalt-ui/core").Config} */
export default {
  tokens: "./tokens.json",
  outDir: "./tokens/",
  plugins: [
    pluginTailwind(),
    pluginCSS({
      transform(token) {
        if (token.$type === "color") {
          const { r, g, b } = culori.rgb(culori.parse(token.$value));
          return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)].join(" ");
        }
      },
    }),
  ],
};

This will generate colors like so:

css
:root {
  --color-blue-1: 251 253 255;
  --color-blue-2: 244 250 255;
  --color-blue-3: 230 244 254;
  --color-blue-4: 213 239 255;
  /* … */
}

For more info, see the docs for plugin-css.