A more elegant way of writing Tailwind classes. Never need to repeating the same variants over and over again π€―.
π Entry point | π¦ Bundle | π¦ Gzip |
---|---|---|
twg |
2721B | 1442B |
twg/lite πͺΆ |
2274B | 1220B |
twg/extend |
2756B | 1272B |
twg/extend/lite πͺΆ |
2138B | 976B |
From v6
, each entry already contains both twg()
and transformer()
[1] function
[1]: Previously called replacer()
function.
- β Elegant.
- β Easy setup.
- β Support for multiple objects parsing.
- β Support for nesting multiple objects, arrays, and itself functions.
- β Support for (multiple) conditional classes, objects, and arrays.
- β
Customizable
callee
name andseparator
. - β
Compatible with wrappers like
twMerge
. - β "Base" support for Tailwind CSS IntelliSense (IDEs extension), as well as Hover Preview.
- β
0 dependencies on
default
version. - β Tree-shaking friendly.
- β Lite version.
Features | default |
default/lite |
extend |
extend/lite |
---|---|---|---|---|
Accept string, number, array, object | β | β | β | β |
Accept template literal | partial | partial | β | β |
Accept multiple outermost objects | β | β | β | β |
Accept nesting objects, arrays | β | β | β | β |
Accept nesting chosen callee inside main object(s) | β | β | ||
Accept nesting custom callee functions inside main object(s) | β | |||
Accept logical conditionals | β | β | β | β |
Accept ternary conditionals | partial | partial | β | β |
Accept native object behavior (key as classes and value as conditionals) | partial | partial | β | β |
Compatible with wrappers | β | β | β | β |
Fully customizable | β | partial | β | partial |
Options |
3 | 1 | 4 | 1 |
|
No. | Framework/Lib | Version | Additional info | Tester | Status |
---|---|---|---|---|---|
1. | next |
15.0.0-canary.156 | With --turbo flag and babel-plugin-react-compiler enabled. |
author | β |
2. | react |
19.0.0-rc-206df66e-20240912 | author | β | |
3. | tailwindcss |
3.4.11 | author | β | |
4. | tailwind-merge |
2.5.2 | author | β |
Click to expand/collapse this section
-
π₯ From
v6.0.2
:- Type
TransformerOptions
(previouslyReplacerOptions
) can now be imported from each entry point.
- Type
-
π₯ From
v6.0.0
:- Rename
replacer()
function totransformer()
. - Remove
*/replacer
entry point,transformer()
now is in the same entry point astwg()
, also withcreateTwg()
function. That meanstransformer()
function will be combined/located in the same file withtwg()
, to take advantage of its API without rewrite it in another entry. - ~25% lighter bundle size in overall.
- Rename
-
π₯ From
v5.0.3
:- Enable
tree-shaking
for the package.
- Enable
-
π₯ From
v5.0.0
:- From now if you want to use custom
separator
option, you need to define theseparator
option in newcreateTwg()
function (previously in the last Object oftwg()
function) and also intransformer()
function like previous version.
- From now if you want to use custom
-
π₯ From
v4.0.0
:- Make
extend
version (which previously called AST version) as optional entry point. From now if you want to useextend
version, you need to install 4 more@babel
dependencies, refer to docs. - Default version now using
combiner()
which written in native JS to parse conditionals (use with limitations).
- Make
-
π₯ From
v3.1.0
:-
Supports nesting custom callee functions through
nestingCallee
option (default version only).transform: { DEFAULT: transformer({ // Define options here, eg.: callee: "twg", nestingCallee: ["cn", "twg"] }) }
Usage: see custom
nestingCallee
.
-
-
π₯ From
v2.0.0
:-
Supports native objects behavior like
clsx
(Key as classes and value as conditionals)twg({ foo: true, bar: false, baz: isTrue() }); //=> "foo baz" twg({ "you are": true, not: false, m_y: 1, "destiny": isTrue() }); //=> "you are m_y destiny"
-
Use
@babel
AST to parse all conditional classes, objects, arrays or even both string and array.- Pros:
- More accurate, more trust in processing.
- Works perfectly even with complex conditionals like nested ternary and inside template literal.
- Reduce several complex regex use to parse condition.
- Resolve all outstanding issues related to any kind of conditionals, nested conditionals.
- Cons:
- Currently work on (.js, .ts, .jsx, .tsx) file only.
- A bit slower, especially on the first time, when nothing is cached.
- 4 more dependencies π’
- Pros:
-
-
π₯ Lite version:
Same as default, but:
- Without any options API except for custom
callee
intransformer()
options. - No
debug messages
(no console messages). - No
JSDoc
comments for each function. - 20 ~ 30% lighter.
- Compile 200 ~ 300ms faster (
extend
version).
- Without any options API except for custom
[!TIP] When you tested using with default version, and everything's OK. So you could want to use lite version, for better performance.
Tip
Simply open an Object, put the variant
as key, and classes you want to map to that variant
as each value.
And if you want to nest other variants inside a variant, you can open an Array and start use it like you've just call a callee function. See usage / use cases for more details.
Example:
<div className={twg(
"size-92 relative grid place-items-center",
{
before: "absolute inset-0 bg-red-500",
"aria-expanded": "bg-red-500 text-yellow-500",
}
)}>
Hello, World!
</div>
Output (html):
<div class="size-92 relative grid place-items-center before:absolute before:inset-0 before:bg-red-500 aria-expanded:bg-red-500 aria-expanded:text-yellow-500">
Hello, World!
</div>
1. Install the package
pnpm add twg
or
npm install twg
2. Setup
// tailwind.config.ts
import { type Config } from "tailwindcss"
import { transformer } from "twg"
export default {
content: {
files: [
"./src/app/**/*.{ts,tsx}",
"./src/components/**/*.{ts,tsx}",
], // Move your old `content` to `content.files` like this
transform: {
DEFAULT: transformer() // Put `transformer()` here
}
},
// Other configurations...
} satisfies Config
-
Lite version:
// tailwind.config.ts import { transformer } from "twg/lite" // Rest like above
-
If you need to override default
transformer()
options:transform: { DEFAULT: transformer({ // Define options here, eg.: callee: "cn" }) }
See all options and how to custom options.
3. Use
import { twg } from "twg"
-
Lite version:
import { twg } from "twg/lite"
-
If you need to override default
twg()
options, you need to usecreateTwg()
function (not for lite version):import { createTwg } from "twg" createTwg({ separator: "_" })( //... )
See custom
separator
.
DONE!
Note
You need to install 4 more @babel
dependencies in order to use extend
version. Besides that, you just need to change the import statement from twg/*
to twg/extend/*
.
1. Install the package
pnpm add twg @babel/generator @babel/parser @babel/traverse @babel/types
or
npm install twg @babel/generator @babel/parser @babel/traverse @babel/types
2. Setup
// tailwind.config.ts
import { type Config } from "tailwindcss"
import { transformer } from "twg/extend"
export default {
content: {
files: [
"./src/app/**/*.{ts,tsx}",
"./src/components/**/*.{ts,tsx}",
], // Move your old `content` to `content.files` like this
transform: {
DEFAULT: transformer() // Put `transformer()` here
}
},
// Other configurations...
} satisfies Config
-
Lite version:
// tailwind.config.ts import { transformer } from "twg/extend/lite" // Rest like above
-
If you need to override default
transformer()
options:transform: { DEFAULT: transformer({ // Define options here, eg.: callee: "cn" }) }
See all options and how to custom options.
3. Use
import { twg } from "twg/extend"
-
Lite version:
import { twg } from "twg/extend/lite"
-
If you need to override default
twg()
options, you need to usecreateTwg()
function (not for lite version):import { createTwg } from "twg/extend" createTwg({ separator: "_" })( //... )
See custom
separator
.
DONE!
For more information, consider reading custom options
See how to use on docs π.
- Migration Guide
βοΈ - Usage / Use cases
βοΈ - Usage
βοΈ - Basic usage
βοΈ - Complex as β οΈ usage
βοΈ
- Basic usage
- Use cases
βοΈ - Conditionals
βοΈ - Nesting callee functions
βοΈ
- Conditionals
- Combination
βοΈ
- Usage
- Options
βοΈ transformer()
optionsβοΈ twg
optionsβοΈ - Custom options
βοΈ - Custom
callee
βοΈ - Custom
nestingCallee
βοΈ - Custom
separator
βοΈ - Turn off
debug
βοΈ
- Custom
- API
βοΈ - Deeper explanation
βοΈ - What is
twg
?βοΈ - Explanation
βοΈ - Trade-offs
βοΈ
- What is
For full & latest update changelog, please refer to CHANGELOG.md.
twg
now work for me but maybe not for you in some edges. Consider opening an issue if you have any problem with it that I can fix it ASAP. Or a pull request is welcome too.
If you have any ideas, feel free to open a feature request template or make a pull request to share your ideas.
For Development and more information on contributing please read CONTRIBUTING.md.
- easy-tailwind
βοΈ - clsx
βοΈ - tailwind-merge
βοΈ content.transform
APIβοΈ
- August 15, 2024
https://www.linkedin.com/in/hoangnhan2ka3/