Skip to main content

Setup

One line of build config for Vite, Next.js or any other PostCSS setup. No tailess config file, no CSS changes, nothing to commit.

Vite

React, Vue, Svelte, Solid, Qwik, Astro — anything on Vite.

vite.config.ts
// vite.config.tsimport { defineConfig } from "vite";import tailwindcss from "@tailwindcss/vite";import tailess from "tailess/vite"; export default defineConfig({  plugins: [tailwindcss(), tailess()],});

Order in the array does not matter — the hook is registered order: "pre", so it always runs before Tailwind wherever you put it. A CommonJS config works the same way: require("tailess/vite") is the plugin itself.

Next.js

Add it to the postcss.config.mjs that create-next-app already generated, before @tailwindcss/postcss.

postcss.config.mjs
// postcss.config.mjsconst config = {  plugins: {    "tailess/postcss": {},    "@tailwindcss/postcss": {},  },}; export default config;

Works with Turbopack and webpack, in dev and build.

Other PostCSS setups

The same postcss.config.* works for Remix, Astro-with-PostCSS, Nuxt, the PostCSS CLI, and anything else in that family — including the array form.

Array form
module.exports = {  plugins: [require("tailess/postcss")(), require("@tailwindcss/postcss")()],};

On Vite, use tailess/vite — not tailess/postcss

@tailwindcss/vite compiles CSS in a pre transform, which runs beforeVite's PostCSS stage, so a PostCSS plugin can never reach it. If your Vite project gets Tailwind through postcss.config.* rather than @tailwindcss/vite, then the PostCSS plugin is the right one.

The whole setup

That is every configuration change there is — no tailess.config, nothing added to your CSS, and no generated file to commit. What is left is the import:

Usage
import { ss } from "tailess";
  • The ss API — the groups you can write once the plugin is in place.
  • Plugin options — what to pass when your source lives outside the default root, as in a monorepo.
  • Troubleshooting — what to check if a class still comes out unstyled.