u/Electronic-Stick7492

Got tired of writing hover:, group: repeatedly in Tailwind, so I made this
▲ 0 r/css+1 crossposts

Got tired of writing hover:, group: repeatedly in Tailwind, so I made this

I kept ending up with Tailwind class strings that looked like this:

className="px-4 py-2 rounded hover:bg-blue-500 hover:text-white hover:shadow-lg focus:ring-2 focus:ring-offset-2 focus:outline-none active:scale-95"

After doing this repeatedly across components, I made a tiny utility called tw-variant to group variant prefixes automatically.

Example:

import { tv } from "tw-variant"

const buttonStyles = tv({
  base: "px-4 py-2 rounded font-medium transition-all",
  hover: "bg-blue-500 text-white shadow-lg",
  focus: "ring-2 ring-offset-2 outline-none",
  active: "scale-95",
  dark: "bg-gray-900 text-white"
})

Generated output:

"px-4 py-2 rounded font-medium transition-all hover:bg-blue-500 hover:text-white hover:shadow-lg focus:ring-2 focus:ring-offset-2 focus:outline-none active:scale-95 dark:bg-gray-900 dark:text-white"

Why I made it:

  • reduces repeated hover: / focus: / dark: prefixes
  • keeps Tailwind class strings easier to read
  • works with any Tailwind variant
  • tiny + zero dependencies
  • full TypeScript support

Works nicely alongside clsx, cn, or tailwind-merge.

import clsx from "clsx"

className={clsx(
  tv({
    hover: "shadow-lg",
    focus: "ring-2",
    dark: "bg-gray-900"
  }),
  isDisabled && "opacity-50"
)}

Install:

npm install tw-variant

Github: https://github.com/kushalxcoder/tw-variant
NPM: https://www.npmjs.com/package/tw-variant

Would genuinely love feedback/suggestions/improvements.

u/Electronic-Stick7492 — 2 days ago