npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tailwind-modifier-aliasing

v0.1.0

Published

A tool for Tailwind CSS to enable modifier reuse

Downloads

2

Readme

tailwind-modifier-aliasing

A cli tool for TailwindCSS that allows you to apply one stack of modifiers to several utility classes. It's a postprocessor, so you write normal and valid tailwind classes, intellisense works as intended, warnings are helpful and the type of the frontend framework is irrelevant.

Installation and usage

npm install tailwind-modifier-aliasing

tailwind-ma input.css output.css [--watch]

To run in parallel with tailwind in watch mode in bash:

tailwind -i input.css -o output.css -w & tailwind-ma output.css final.css -w

How it works

First, some of the tailwind classes have to be written in a particular way. Then, this cli tool takes the tailwind generated and unminified output file and rewrites some of the rules to take advantage of native css nesting.

A utility class that defines a property named alias can have its modifiers applied to utility classes that prepend their selectors with the the value of this property. Such classes can be said to depend on the presence of the aliased modifier class that they reference. Take this markup:

<div class="hover:md:[alias:hm] [hm&]:bg-red-500">
  Red on hover when wider than 768px
</div>

Here hm is an alias for hover:md, and [hm&] is a reference that can be used to apply the modifiers to bg-red-500. Given this markup tailwind generates these two rules:

@media (min-width: 768px) {
  .hover\:md\:\[alias\:hm\]:hover {
    alias: hm;
  }
}

hm.\[hm\&\]\:bg-red-500 {
  //...
}

which are then rewritten by this tool into this:

@media (min-width: 768px) {
  :is(.hover\:md\:\[alias\:hm\]:hover) {
    &.\[hm\&\]\:bg-red-500 {
      //...
    }
  }
}

which has the same effect as hover:md:bg-red-500.

An element can have several aliased classes, each must have a different alias to avoid conflicts. Also, dependent classes can have additional modifiers of their own.

<div class="hover:peer-[:not(:placeholder-shown)]:[alias:a] [a&]:bg-blue-300 [a&]:text-sm [a&]:font-bold group-focus/item:last-of-type:[alias:b] [b&]:bg-red-500 [b&]:hover:text-lg [b&]:hover:italic">

The syntax is quite verbose and only suitable for taming some of the more egregious modifiers, but with native support it could look like this hover:md::h h:bg-red-500 h:text-white h:font-bold which is almost as concise as other grouping proposals.

Deduplication

Aliases are global. This tool doesn't examine source files and has no idea which classes actually depend on which. So if the same alias is used by different modifier classes that are dependent on by many other utilities then all their permutations must be supported. Given this markup:

<div class="hover:[alias:a] [a&]:bg-red-500">
  Red
</div>
<div class="focus:[alias:a] [a&]:bg-blue-500" tabindex="0">
  Blue
</div>

tailwind generates this css:

.hover\:\[alias\:a\]:hover {
  alias: a;
}
.focus\:\[alias\:a\]:focus {
  alias: a;
}
// ...two more rules for red and blue

and now both bg-red-500 and bg-blue-500 rules have to be copied into each of those aliased rules. This tool tries to tackle the problem by deduplicating aliased rules, so the final css is actually this:

:is(.focus\:\[alias\:a\]:focus,
.hover\:\[alias\:a\]:hover) {
  &.\[a\&\]\:bg-blue-500 {
    //...
  }
  &.\[a\&\]\:bg-red-500 {
    //...
  }
}

Wrapping the selector list in the :is pseudo-class function ensures that one unsupported selector doesn't invalidate the entire list.

Deduping is only possible for aliased rules that belong to the same at-rule. For example, given these classes: hover:md:[alias:a], hover:sm:[alias:a], hover:md:dark:[alias:a], hover:[alias:a] tailwind generates this css:

.hover\:\[alias\:a\]:hover {
  alias: a;
}
@media (min-width: 640px) {
  .hover\:sm\:\[alias\:a\]:hover {
    alias: a;
  }
}
@media (min-width: 768px) {
  .hover\:md\:\[alias\:a\]:hover {
    alias: a;
  }
  @media (prefers-color-scheme: dark) {
    .hover\:md\:dark\:\[alias\:a\]:hover {
      alias: a;
    }
  }
}

None of the above rules will be deduped. The tool reports the amount of dependent rules it initally finds and the amount of copies it makes to help see if this becomes a problem.

Considerations

Modifiers that target anything but their own element, like marker or *, can't be aliased. Modifiers that target pseudo-elements are moved to the dependent rule's selector, so this limitation doesn't apply to them. However, it does negatively affect deduping.

<div class="before:md:hover:[alias:bmh] [bmh&]:dark:peer-invalid:font-bold ..."></div>

The tailwind generated css for the above markup is:

@media (min-width: 768px) {
  .before\:md\:hover\:\[alias\:bmh\]:hover::before {
    content: var(--tw-content);
    alias: bmh;
  }
}

@media (prefers-color-scheme: dark) {
  bmh.peer:invalid ~ .\[bmh\&\]\:dark\:peer-invalid\:font-bold {
    font-weight: 700;
  }
}

Then, ::before is cut from the outer and appended to the inner selector. The content property is also moved:

@media (min-width: 768px) {
  :is(.before\:md\:hover\:\[alias\:bmh\]:hover) {
    @media (prefers-color-scheme: dark) {
      .peer:invalid ~ &.\[bmh\&\]\:dark\:peer-invalid\:font-bold::before {
        content: var(--tw-content);
        font-weight: 700;
      }
    }
  }
}

Modifiers that target children are allowed in dependent classes, but they make other modifiers apply to the target element and not to the children. For example, hover:[alias:a] [a&]:marker:text-sky-500 works the same as marker:hover:text-sky-500 and not as hover:marker:text-sky-500.