An Angular standalone directive that merges Tailwind CSS classes using tailwind-merge and clsx
npm install ng-tailwind-mergeclass and ngClass using tailwind-merge and clsx. Built on Angular's signal-based inputs.
@angular/core and @angular/common ^17.0.0 (standalone + signal inputs)
tailwind-merge ^3.4.0
clsx ^2.1.1
bash
npm install ng-tailwind-merge
`
Usage (standalone)
$3
Merges class and ngClass attributes:
`typescript
import { Component, signal } from '@angular/core';
import { NgTailwindMerge } from 'ng-tailwind-merge';
@Component({
selector: 'app-example',
standalone: true,
imports: [NgTailwindMerge],
template:
})
export class ExampleComponent {
isActive = signal(true);
}
`
$3
Property binding for dynamic class merging:
`typescript
import { Component, signal } from '@angular/core';
import { NgMerge } from 'ng-tailwind-merge';
@Component({
selector: 'app-example',
standalone: true,
imports: [NgMerge],
template:
})
export class ExampleComponent {
isActive = signal(true);
classes = signal('bg-green-500 p-8 text-white');
}
`
API
$3
Utility function that combines clsx and tailwind-merge for merging class values with Tailwind conflict resolution.
`typescript
import { cn } from 'ng-tailwind-merge';
// String arguments
const merged = cn('bg-red-500', 'bg-blue-500 p-4'); // Returns: 'bg-blue-500 p-4'
// Array and object arguments
const conditionalClasses = cn(
['p-4', 'text-white'],
{ 'bg-blue-500': true, 'bg-red-500': false, 'font-bold': true }
); // Returns: 'p-4 text-white bg-blue-500 font-bold'
// Mixed array with strings and objects
const mixed = cn(
'bg-red-500 p-4',
['text-white', 'm-2'],
{ 'bg-blue-500': true }
); // Returns: 'p-4 text-white m-2 bg-blue-500'
`
$3
Alias for cn(). Explicitly named utility for merging Tailwind classes.
`typescript
import { mergeTailwindClasses } from 'ng-tailwind-merge';
const merged = mergeTailwindClasses('p-4 p-8', 'm-2'); // Returns: 'p-8 m-2'
`
$3
- Selector: [twMerge]
- Behavior: Reads class and ngClass attributes and merges them via tailwind-merge.
$3
- Selector: [merge]
- Input: merge - accepts ClassValue | ClassValue[] (string, string[], object, or mixed array)
- Behavior: Merges the input value(s) and applies the result to the element's class attribute.
$3
Both directives:
- Are standalone (no module required)
- Use signal-based inputs
- Resolve Tailwind conflicts (last variant wins)
- Are tree-shakeable (sideEffects: false)
How it works
- Signal-based inputs read the current values reactively.
- clsx normalizes inputs; tailwind-merge resolves Tailwind conflicts.
- The final merged string is applied to the element's class attribute via effect()`.