Skip to content

About

No description, website, or topics provided.

Resources

Stars

12 stars

Watchers

0 watching

Forks

Repository files navigation

Tailwind CSS Canonical Classes

MIT License Tailwind CSS v4 Node.js >= 18

Automatically convert non-canonical Tailwind CSS v4 classes to their canonical equivalents.

Tailwind CSS v4 introduced a design-system-aware class syntax. When you write arbitrary values like mt-[16px] but a canonical utility mt-4 exists in your design system, this toolset rewrites them for you — keeping your codebase consistent and idiomatic.

- <div class="mt-[16px] text-[red] p-[32px] rounded-[8px]">
+ <div class="mt-4 text-red p-8 rounded-lg">

Packages

Package npm Description
@laststance/tailwindcss-canonical-classes-core npm Core transformation logic
prettier-plugin-tailwindcss-canonical-classes npm Prettier plugin for auto-formatting
@laststance/tailwind-suggest-canonical-classes npm CLI for checking & fixing files

Quick Start

CLI

Check files without modifying them (great for CI):

npx @laststance/tailwind-suggest-canonical-classes "src/**/*.{tsx,jsx,html}" --check

Fix files in place:

npx @laststance/tailwind-suggest-canonical-classes "src/**/*.{tsx,jsx,html}"

If your Tailwind v4 entry stylesheet is not discoverable automatically, pass it explicitly:

npx @laststance/tailwind-suggest-canonical-classes "src/**/*.{tsx,jsx,html}" --css ./app/globals.css

CLI Options

tailwind-suggest-canonical-classes <files/globs> [options]

Options:
  --root <dir>             Project root directory (default: cwd)
  --css <file>             Tailwind v4 entry CSS (default: @import "tailwindcss")
  --root-font-size <num>   Root font size in px (default: 16)
  --check                  Dry run; exit 1 if non-canonical classes are found
  --dry-run                Alias for --check
  --verbose                Print per-file results
  --help                   Show help

Exit Codes

Code Meaning
0 Success — command completed successfully (including --help when a target is present)
1 Failure — missing targets, no matching files, missing Tailwind v4, file errors, or --check found non-canonical classes

Prettier Plugin (Recommended)

The easiest way to adopt canonical classes — they're applied automatically every time you format.

npm install -D prettier-plugin-tailwindcss-canonical-classes prettier tailwindcss

Add to .prettierrc:

{
  "plugins": ["prettier-plugin-tailwindcss-canonical-classes"]
}

That's it. Run prettier --write . and non-canonical classes are rewritten.

With prettier-plugin-tailwindcss (class sorting)

VS Code extension note: Relative tailwindcssCanonicalStylesheet paths are resolved from the Prettier configuration file, matching prettier-plugin-tailwindcss. For nested packages, keep the Prettier config next to the stylesheet owner or use an absolute stylesheet path.

Install both Prettier plugins:

npm install -D prettier prettier-plugin-tailwindcss prettier-plugin-tailwindcss-canonical-classes tailwindcss

List the canonical plugin last so it can canonicalize classes before delegating to the sorting plugin's preprocessing and AST parsing:

{
  "plugins": [
    "prettier-plugin-tailwindcss",
    "prettier-plugin-tailwindcss-canonical-classes"
  ],
  "tailwindStylesheet": "./app/globals.css",
  "tailwindcssCanonicalStylesheet": "./app/globals.css"
}

Both stylesheet options should point to the same Tailwind v4 entry file. Sorting options such as tailwindFunctions are forwarded to prettier-plugin-tailwindcss. A single format pass applies both transformations.

Run Prettier from the command line:

# Check formatting without modifying files
npx prettier --check "src/**/*.{astro,css,html,js,jsx,md,mdx,ts,tsx,vue,svelte}"

# Format files in place
npx prettier --write "src/**/*.{astro,css,html,js,jsx,md,mdx,ts,tsx,vue,svelte}"

Options

Option Type Default Description
tailwindcssCanonicalStylesheet string undefined Path to your Tailwind CSS v4 entry stylesheet, relative to the Prettier configuration file
tailwindcssCanonicalRootFontSize int 16 Root font size in px for rem-based canonicalization
{
  "plugins": ["prettier-plugin-tailwindcss-canonical-classes"],
  "tailwindcssCanonicalStylesheet": "./app/globals.css",
  "tailwindcssCanonicalRootFontSize": 16
}

Core Library

For building custom integrations:

npm install @laststance/tailwindcss-canonical-classes-core tailwindcss
import {
  getDesignSystem,
  canonicalizeDocument,
} from '@laststance/tailwindcss-canonical-classes-core'

const designSystem = await getDesignSystem(process.cwd(), './app/globals.css')

const result = await canonicalizeDocument(
  sourceText,
  'component.tsx',
  designSystem,
  process.cwd(),
  { rootFontSize: 16 },
)

How It Works

This toolset leverages Tailwind CSS v4's __unstable__loadDesignSystem API to understand your project's design system. The transformation pipeline:

Source file
    ↓
Load design system (cached) from your Tailwind v4 config
    ↓
@tailwindcss/language-service validates each class
    → Identifies non-canonical classes via SuggestCanonicalClasses diagnostic
    ↓
designSystem.canonicalizeCandidates() maps to canonical equivalents
    ↓
Text edits applied in reverse order (prevents offset shifting)
    ↓
Canonicalized output

Canonical mappings are not hardcoded — they come directly from your Tailwind v4 design system. If you've customized your theme, the mappings reflect your configuration.

Supported File Types

.astro · .css · .html · .js · .jsx · .less · .md · .mdx · .scss · .svelte · .ts · .tsx · .vue

Monorepo Structure

packages/
├── core/              # @laststance/tailwindcss-canonical-classes-core
│   └── src/
│       ├── canonicalizer.ts   # Transformation pipeline
│       ├── design-system.ts   # Tailwind v4 design system loader
│       ├── types.ts           # Shared types
│       └── index.ts           # Public API
├── cli/               # @laststance/tailwind-suggest-canonical-classes
│   ├── bin/           # CLI entry point
│   └── src/
│       └── cli.ts     # Argument parsing, file processing, reporting
└── prettier-plugin/   # prettier-plugin-tailwindcss-canonical-classes
    └── src/
        ├── index.ts   # Plugin registration & parser wrapping
        ├── parsers.ts # Parser configuration
        └── options.ts # Prettier option definitions
playground/            # Next.js 16 + shadcn/ui test app

Development

Prerequisites

  • Node.js >= 20.19 (the sorting plugin used by the tests requires it)
  • pnpm 10.x

Setup

git clone https://github.com/laststance/tailwindcss-canonical-classes-monrepo.git
cd tailwindcss-canonical-classes-monrepo
pnpm install

Build

pnpm build          # Build all packages
pnpm typecheck      # Type check all packages
pnpm clean          # Remove dist/ from all packages

Package Tests

Build core first so dependent packages can resolve its declarations. The Prettier plugin test command rebuilds the plugin before running its tests.

pnpm --filter @laststance/tailwindcss-canonical-classes-core build
pnpm --filter prettier-plugin-tailwindcss-canonical-classes test

Testing with the Playground

The playground is a Next.js 16 + shadcn/ui app for manual testing:

cd playground
pnpm dev             # Start dev server
pnpm format          # Run Prettier with canonical plugin
pnpm format:check    # Check without modifying

Note: Discard playground changes after testing: git checkout playground/

Requirements

When combining with prettier-plugin-tailwindcss, also satisfy its runtime requirements; version 0.8.1 requires Node.js >= 20.19.

  • Tailwind CSS v4 — uses v4's design system API (__unstable__loadDesignSystem)
  • Node.js >= 18
  • Prettier >= 3.7.0 and < 4 (async parser preprocessing requires 3.7.0)

License

MIT © Laststance.io

About

No description, website, or topics provided.

Resources

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages