Tailwindest

Setup

How to set up tailwindest in your project.

1. Install packages

Install tailwindest for core functionalities, and create-tailwind-type to generate types from your tailwind.css.

npm i tailwindest
bun add tailwindest
pnpm add tailwindest
yarn add tailwindest

2. Generate Tailwind types

Run the following command to generate Tailwind type files in your project root.

npx create-tailwind-type

This creates:

  • tailwind.ts: Tailwind and TailwindNestGroups for typed style objects.
  • tailwind_literal.ts: TailwindLiteral for typed class string arguments.

Generated arbitrary value template types and slash modifier variant template types are disabled by default for TypeScript performance. You can still allow arbitrary class strings through useArbitrary: true in your tw.ts setup. Use useArbitraryNestGroups: true when you want arbitrary or dynamic variant object keys such as [&_p], data-[size=large], aria-invalid, data-state, group-[.is-published], or group-aria-invalid. Known generated nest groups keep exact prefixed value checking. Values inside arbitrary or dynamic nest group keys are intentionally typed as class strings instead of exact ${key}:${literal} unions to avoid TypeScript TS2590 on large Tailwind outputs.

You can customize the output path and other options. Check out the create-tailwind-type documentation for more details.

3. Create styling tools

Create a tw.ts (or tw.js) file to define your tailwindest tools.

import { createTools, type CreateTailwindest } from "tailwindest"

import type { Tailwind, TailwindNestGroups } from "./tailwind" // Adjust path if needed
import type { TailwindLiteral } from "./tailwind_literal" // Generated literal file

import { twMerge } from "tailwind-merge"

// Create the main Tailwindest type
export type Tailwindest = CreateTailwindest<{
    tailwind: Tailwind
    tailwindNestGroups: TailwindNestGroups

    // Optional: customize prefix for screen/variant groups

    // groupPrefix: "$" <-- prefix for group variants
    useArbitrary: true // enable arbitrary values, type-hinting is available for this option
    useArbitraryNestGroups: true // enable arbitrary/dynamic variant object keys like "[&_p]" or "aria-invalid"
}>

// Create the tools
export const tw = createTools<{
    tailwindest: Tailwindest
    tailwindLiteral: TailwindLiteral
    useArbitrary: true
    useTypedClassLiteral: true // enables typed literal classes at tw.style().class(...typed literals)
}>({
    // Optional: if you use tailwind-merge
    merger: twMerge, // <-- tailwind-merge as classname merger
})

4. Exclude generated types from your tailwind.css

Make sure to exclude the generated type files from your tailwind.css file to prevent all-css from being included in the generated CSS.

@import "tailwindcss";
/* IMPORTANT */
/* Specify not-include generated type definitions */
@source not "tailwind.ts";
@source not "tailwind_literal.ts";

/* Your Tailwind CSS styles here */

Now you're all set! You can import tw from tw.ts and start creating typed styles.

On this page