Automatically sorting your Tailwind CSS class names
Tags: tailwindcss, linting, vscode, githooks
Published: 2021-06-08 21:28:38

When Steve Jobs returned to Apple he opted to make one less decision everyday: he always wore the same black top. He was now liberated to make one additional, more important, decision during his day. I've been making tiny decisions every day and I want to be set free: I do not want to decide the order of my Tailwind CSS classes.

I want tools to do it. Tools that everyone on the team today and in the future will keep using consistently.

Never again will I need to decide the ordering of CSS classes in my HTML:

```html
<div class="flex flex-grow-0 justify-between items-center px-2 -mt-7 text-xs text-white uppercase">
  <div class="flex items-center space-x-2">
    <div class="flex justify-center items-center w-5 h-5 text-gray-900 rounded-full bg-brand-primary-surface">
```

Well known Tailwind CSS utility classes are sorted first, and bespoke classes come last. What is the ordering of utility classes? Why is `flex` before `w-5` which is before `text-gray-900`?

Who cares. You don't either. Let the tools below do their job and everyone's CSS class names will look the same, and look fantastic.

There are three tools that help:

* [Headwind](https://github.com/ryanhhhh/headwind) - a VS Code extension that sorts your CSS classes on save
* [Rustywind](https://github.com/avencera/rustywind) - a CLI that can update all your files' CSS classes at once
* [Overcommit](https://github.com/sds/overcommit) - run `rustywind --write` during `git commit` to update your files before you send them off to git

Update: [@fractaledmind](https://dev.to/fractaledmind) fixed an issue where `rustywind` is installed via `package.json` -- we must wrap it in an `npm run rustywind-fix` script.

## Headwind

I use VS Code and once of its exemplar qualities is the magnificent library of community extensions. VS Code provides the ability for one or more installed extensions to run when you save a file. This is brilliant for automatically formatting your file before it hits the disk. Let's use this hook to format any series of CSS class names in our file.

Enter, [Headwind](https://github.com/ryanhhhh/headwind).

[Install it into VS Code](https://marketplace.visualstudio.com/items?itemName=heybourn.headwind), go to any of your HTML files, re-save the file and BOOM!! all the series of CSS class names are reordered consistently.

## Rustywind

This is great for you. You installed the VS Code extension. Unfortunately, statically speaking, someone you work with uses Vim. You know who they are because they would have told you.

So let's take steps towards ensuring everyone who works on your projects is always formatting their CSS class name lists using the same tool.

Enter, [Rustywind](https://github.com/avencera/rustywind). It is a CLI `rustywind` that is installed via npm but written in Rust. I didn't know you could do that either.

From what I read, Rustywind was inspired by Headwind, but now looks to be used by Headwind itself. Very nice.

You can fix a single file with `rustywind`:

```
rustywind path/to/my/template.html --write
```

Or fix all the files:

```
rustywind . --write
```

To ensure everyone installs `rustywind`, add it to your project's `package.json` with `npm` or `yarn` to taste:

```bash
$ yarn install -D rustywind

# or

$ npm i --save-dev rustywind
```

Everyone will have `rustywind` installed into the application when they next run `npm i` or `yarn`.

Next, create a local npm script in your `package.json`:

```json
  "scripts": {
    "rustywind-fix": "rustywind --write ."
  },
```

Any developers of your repository can now access the local `rustywind` via:

```
npm run rustywind-fix
```

## Overcommit

Finally, let's help everyone run `rustywind` all the time. Or, at least, run it before they commit their files to the Git repository.

If you're familiar with `git` hooks, you'll know you could create or edit `.git/hooks/pre-commit` and run the `rustywind . --write` command. Alas, these git hooks are local to you. Your hooks aren't assured to be the same as everyone else. You're formatting with `rustywind` but no one else is.

Fortunately, you can share git hooks, and make them pretty. How pretty?

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7y1cc97rn20rix7wahmc.png) 

Yes, you want that now, I know.

Enter, [Overcommit](https://github.com/sds/overcommit): a tool to manage and configure Git hooks.

Create a configuration file for your project that runs Rustywind called `.overcommit.yml`:

```yaml
PreCommit:
  Rustywind:
    enabled: true
    required: true
    command: ['npm', 'run', 'rustywind-fix']
```

Now that you've added this `.overcommit.yml` file to the root of your git repo, we now need everyone to do something for the greater good. They need to install Overcommit and activate it for their local git clone.

Overcommit is a CLI that is distributed as a RubyGem.

```
gem install overcommit
```

If your project is a Ruby project with a `Gemfile`, then add the gem:

```ruby
group :development do
  # A fully configurable and extendable Git hook manager
  gem "overcommit"
end
```

And run `bundle install`. I like this best.

The second manual step for everyone is to activate the Git hooks. Everyone needs to run:

```
overcommit
```

Thanks everyone. You're making the world a better place. Next, net zero carbon emissions.

Every developer will now see Rustywind during their next commit.

```
$ git commit -a -m "Doing the things"
Running pre-commit hooks
Run Rustywind.............................................[Rustywind] OK

✓ All pre-commit hooks passed
```

If you're a Ruby developer and also want everyone to run the Ruby formatter and linter StandardRB, then extend your `.overcommit.yml` file:

```yaml
PreCommit:
  Rustywind:
    enabled: true
    required: true
    command: ['npm', 'run', 'rustywind-fix']
  StandardRB:
    enabled: true
    required: true
    command: ['bundle', 'exec', 'standardrb'] # Invoke within Bundler context
    flags: ['--fix']
```

When you commit the two commands `rustywind` and `standardrb --fix` will be run in parallel:

```
$ git commit -a -m "Doing the things"
Running pre-commit hooks
Run Rustywind.............................................[Rustywind] OK
Run StandardRB...........................................[StandardRB] OK

✓ All pre-commit hooks passed
```

## Freedom by abdication

"But I don't agree with the order that Rustywind sorts the classes!"

Whether its a syntax formatter for your programming language whitespace or a tiny tool that has a preference for CSS class orders, just pick one and let it care more than you do. It will consistently do its thing over and over.

You really don't care that much about the order of the classes to not use a free, instant, shareable, pretty, and consistent tool do you?