{"id":13480100,"url":"https://github.com/heybourn/headwind","last_synced_at":"2025-05-16T01:04:20.228Z","repository":{"id":41380742,"uuid":"222946562","full_name":"heybourn/headwind","owner":"heybourn","description":"An opinionated Tailwind CSS class sorter built for Visual Studio Code","archived":false,"fork":false,"pushed_at":"2023-07-29T15:50:22.000Z","size":7715,"stargazers_count":1397,"open_issues_count":89,"forks_count":47,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-08T11:14:33.665Z","etag":null,"topics":["css","formatter","sorter","tailwind-css","tailwindcss","visual-studio-code","visual-studio-extension"],"latest_commit_sha":null,"homepage":"https://marketplace.visualstudio.com/items?itemName=heybourn.headwind","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/heybourn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"open_collective":"headwind"}},"created_at":"2019-11-20T13:42:25.000Z","updated_at":"2025-04-08T08:38:09.000Z","dependencies_parsed_at":"2024-01-07T21:16:45.747Z","dependency_job_id":null,"html_url":"https://github.com/heybourn/headwind","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heybourn%2Fheadwind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heybourn%2Fheadwind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heybourn%2Fheadwind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/heybourn%2Fheadwind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/heybourn","download_url":"https://codeload.github.com/heybourn/headwind/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254448579,"owners_count":22072764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","formatter","sorter","tailwind-css","tailwindcss","visual-studio-code","visual-studio-extension"],"created_at":"2024-07-31T17:00:34.604Z","updated_at":"2025-05-16T01:04:20.203Z","avatar_url":"https://github.com/heybourn.png","language":"TypeScript","readme":"# Headwind\n\n[![CircleCI](https://circleci.com/gh/heybourn/headwind.svg?style=svg)](https://circleci.com/gh/heybourn/headwind)\n\nHeadwind is an opinionated Tailwind CSS class sorter for Visual Studio Code. It enforces consistent ordering of classes by parsing your code and reprinting class tags to follow a given order.\n\n\u003e Headwind runs on save, will remove duplicate classes and can even sort entire workspaces.\n\n---\n\n**[Get it from the VS Code Marketplace →](https://marketplace.visualstudio.com/items?itemName=heybourn.headwind)**\n\n**[Use PHPStorm? Get @WalrusSoup's Headwind port →](https://plugins.jetbrains.com/plugin/13376-tailwind-formatter/)**\n\n\u003cimg src=\"https://github.com/heybourn/headwind/blob/master/img/explainer.gif?raw=true\" alt=\"Explainer\" width=\"750px\"\u003e\n\n## Usage\n\nYou can install Headwind via the VS Code Marketplace, or package it yourself using [vsce](https://code.visualstudio.com/api/working-with-extensions/publishing-extension). Headwind works globally once installed and will run on save if a `tailwind.config.js` file is present within your working directory.\n\nYou can also trigger Headwind by:\n\n* Pressing ALT + Shift + T on Mac\n* Pressing CTRL + ALT + T on Windows\n* Pressing CTRL + ALT + T on Linux\n\n\nHeadwind can sort individual files by running 'Sort Tailwind CSS Classes' via the Command Palette. Workspaces can also be sorted by running 'Sort Tailwind CSS Classes on Entire Workspace'.\n\nAny breakpoints or unknown classes will be moved to the end of the class list, whilst duplicate classes will be removed.\n\n## Customisation\n\nHeadwind ships with a default class order (located in [package.json](package.json)). You can edit this (and other settings) to your liking on the extension settings page.\n\n### `headwind.classRegex`:\n\nAn object with language IDs as keys and their values determining the regex to search for Tailwind CSS classes.\nThe default is located in [package.json](package.json) but this can be customized to suit your needs.\n\nThere can be multiple capturing groups, that should only contain a string with Tailwind CSS classes (without any apostrophies etc.). If a new group, which doesn't contain the `class` string, is created, ensure that it is non-capturing by using `(?:)`.\n\nExample from `package.json`:\n\n```json\n\"headwind.classRegex\": {\n    \"html\": \"\\\\bclass\\\\s*=\\\\s*[\\\\\\\"\\\\']([_a-zA-Z0-9\\\\s\\\\-\\\\:\\\\/]+)[\\\\\\\"\\\\']\",\n    \"javascriptreact\": \"(?:\\\\bclassName\\\\s*=\\\\s*[\\\\\\\"\\\\']([_a-zA-Z0-9\\\\s\\\\-\\\\:\\\\/]+)[\\\\\\\"\\\\'])|(?:\\\\btw\\\\s*`([_a-zA-Z0-9\\\\s\\\\-\\\\:\\\\/]*)`)\"\n}\n```\n\n#### Multi-step Regex\n\nA multi-step regex can be specified by using an array of regexes to be executed in order.\n\nExample from `package.json`:\n\n```js\n\"headwind.classRegex\": {\n    \"javascript\": [\n        \"(?:\\\\bclass(?:Name)?\\\\s*=\\\\s*(?:{([\\\\w\\\\d\\\\s_\\\\-:/${}()[\\\\]\\\"'`,]+)})|([\\\"'`][\\\\w\\\\d\\\\s_\\\\-:/]+[\\\"'`]))|(?:\\\\btw\\\\s*(`[\\\\w\\\\d\\\\s_\\\\-:/]+`))\",\n        \"(?:[\\\"'`]([\\\\w\\\\d\\\\s_\\\\-:/${}()[\\\\]\\\"']+)[\\\"'`])\"\n    ],\n}\n```\n\nThe first regex will look for JSX `class` or `className` attributes or [twin.macro](https://github.com/ben-rogerson/twin.macro) usage.\n\nThe second regex will then look for class names to be sorted within these matches.\n\n#### Configuration Object\n\nOptionally a configuration object can be passed to specify additional options for sorting class names.\n\n- `regex` - specifies the regex to be used to find class names\n- `separator` - regex pattern that is used to separate class names (default: `\"\\\\s+\"`)\n- `replacement` - string used to replace separator matches (default: `\" \"`)\n\nExample from `package.json`:\n\n```js\n\"headwind.classRegex\": {\n    \"jade\": [\n        {\n            \"regex\": \"\\\\.([\\\\._a-zA-Z0-9\\\\-]+)\",\n            \"separator\": \"\\\\.\",\n            \"replacement\": \".\"\n        },\n        \"\\\\bclass\\\\s*=\\\\s*[\\\\\\\"\\\\']([_a-zA-Z0-9\\\\s\\\\-\\\\:\\\\/]+)[\\\\\\\"\\\\']\"\n    ],\n}\n```\n\n#### Debugging Custom Regex:\n\nTo debug custom `classRegex`, you can use the code below:\n```js\n// Your test string here\nconst editorText = `\n  export const Layout = ({ children }) =\u003e (\n    \u003cdiv class=\"h-screen\"\u003e\n      \u003cdiv className=\"w-64 h-full bg-blue-400 relative\"\u003e\u003c/div\u003e\n      \u003cdiv\u003e{children}\u003c/div\u003e\n    \u003c/div\u003e\n  )\n`\n// Your Regex here\nconst regex = /(?:\\b(?:class|className)?\\s*=\\s*{?[\\\"\\']([_a-zA-Z0-9\\s\\-\\:/]+)[\\\"\\']}?)/\nconst classWrapperRegex = new RegExp(regex, 'gi')\n\nlet classWrapper\nwhile ((classWrapper = classWrapperRegex.exec(editorText)) !== null) {\n  const wrapperMatch = classWrapper[0]\n  const valueMatchIndex = classWrapper.findIndex((match, idx) =\u003e idx !== 0 \u0026\u0026 match)\n  const valueMatch = classWrapper[valueMatchIndex]\n\n  console.log('classWrapper', classWrapper)\n  console.log('wrapperMatch', wrapperMatch)\n  console.log('valueMatchIndex', valueMatchIndex)\n  console.log('valueMatch', valueMatch)\n}\n```\n\nThe result of `valueMatch` should be the class text _exactly_, with no other characters.\n\nGood example value: `valueMatch w-64 h-full bg-blue-400 relative`\n\n**Note**: Changes made to Headwind's JSON configuration options may not take effect immediately. When experimenting with custom `classRegex`, after each change you should open the control pallete (Ctrl/Cmd + Shift + P) and run `Developer: Reload Window` to ensure changes are applied.\n\n\u003chr\u003e\n\n### `headwind.defaultSortOrder`:\n\nAn array that determines Headwind's default sort order.\n\n### `headwind.removeDuplicates`:\n\nHeadwind will remove duplicate class names by default. This can be toggled on or off.\n\n`\"headwind.removeDuplicates\": false`\n\n### `headwind.prependCustomClasses`:\n\nHeadwind will append custom class names by default. They can be prepended instead.\n\n`\"headwind.prependCustomClasses\": true`\n\n### `headwind.runOnSave`:\n\nHeadwind will run on save by default (if a `tailwind.config.js` file is present within your working directory). This can be toggled on or off.\n\n`\"headwind.runOnSave\": false`\n\n## Contributing\n\nHeadwind is open-source and contributions are always welcome. If you're interested in submitting a pull request, please take a moment to review [CONTRIBUTING.md](.github/CONTRIBUTING.md).\n\n## Contributors\n\n### Code Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n\u003ca href=\"https://github.com/heybourn/headwind/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/headwind/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n### Financial Contributors\n\nBecome a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/headwind/contribute)]\n\n#### Individuals\n\n\u003ca href=\"https://opencollective.com/headwind\"\u003e\u003cimg src=\"https://opencollective.com/headwind/individuals.svg?width=890\"\u003e\u003c/a\u003e\n\n#### Organizations\n\nSupport this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/headwind/contribute)]\n\n\u003ca href=\"https://opencollective.com/headwind/organization/0/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/1/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/2/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/3/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/4/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/5/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/6/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/7/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/8/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/headwind/organization/9/website\"\u003e\u003cimg src=\"https://opencollective.com/headwind/organization/9/avatar.svg\"\u003e\u003c/a\u003e\n","funding_links":["https://opencollective.com/headwind","https://opencollective.com/headwind/contribute","https://opencollective.com/headwind/organization/0/website","https://opencollective.com/headwind/organization/1/website","https://opencollective.com/headwind/organization/2/website","https://opencollective.com/headwind/organization/3/website","https://opencollective.com/headwind/organization/4/website","https://opencollective.com/headwind/organization/5/website","https://opencollective.com/headwind/organization/6/website","https://opencollective.com/headwind/organization/7/website","https://opencollective.com/headwind/organization/8/website","https://opencollective.com/headwind/organization/9/website"],"categories":["IDE Extensions","TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheybourn%2Fheadwind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fheybourn%2Fheadwind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheybourn%2Fheadwind/lists"}