TwMerge 1.0.7

dotnet add package TwMerge --version 1.0.7
                    
NuGet\Install-Package TwMerge -Version 1.0.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TwMerge" Version="1.0.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TwMerge" Version="1.0.7" />
                    
Directory.Packages.props
<PackageReference Include="TwMerge" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TwMerge --version 1.0.7
                    
#r "nuget: TwMerge, 1.0.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TwMerge@1.0.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TwMerge&version=1.0.7
                    
Install as a Cake Addin
#tool nuget:?package=TwMerge&version=1.0.7
                    
Install as a Cake Tool

TailwindMerge Logo

TwMerge 🍃

NuGet Version

A high-performance .NET library for merging Tailwind CSS class names with full conflict resolution, deduplication, and support for all major Tailwind v4 utilities, responsive breakpoints, and modifiers.

Features

  • Tailwind v4 Support: Handles all major class groups, including text, font, spacing, layout, color, and more
  • Conflict Resolution: Automatically removes conflicting or duplicate classes, keeping only the last in each group
  • Responsive & Modifier Aware: Correctly merges classes with responsive prefixes (sm:, md:, etc.) and modifiers (hover:, focus:, dark:, etc.)
  • Arbitrary Value Support: Handles arbitrary values and custom properties (e.g., w-[32px])
  • High Performance: Zero-allocation merging with LRU caching for repeated merges
  • Customizable: Extend or override class groups and conflict rules via configuration

Installation

dotnet add package TwMerge

Quick Start

  1. Add TailwindMerge to your project and create a merger instance:
using TailwindMerge;
 
// Create instance with default config
var twMerge = new TwMerge(); 
  1. Merge Tailwind class names:
// merged == "w-4 hover:w-4 text-blue-500"
var merged = twMerge.Merge("w-3", "w-4", "hover:w-3", "hover:w-4", "text-red-500", "text-blue-500"); 

Core Components

TwMerge

The main entry point for merging Tailwind CSS class names, resolving conflicts and removing duplicates.

TwConfig

Configures class groups, conflict rules, theme, and other options. Use TwConfig.Default() for standard Tailwind v4 support, or customize as needed.

TwConfig Properties Reference

Each property in TwConfig serves a specific purpose in controlling how Tailwind classes are merged and resolved:

CacheSize

Type: int (default: 500)
Purpose: Controls the size of the LRU cache for memoizing merge results.

var config = new TwConfig().CacheSize(1000); // Increase cache for better performance

When to customize:

  • Increase for applications with many repeated class combinations
  • Decrease for memory-constrained environments
  • Set to 0 to disable caching entirely

Separator

Type: string (default: ":")
Purpose: Defines the character(s) used to separate modifiers from base classes.

var config = new TwConfig().Separator("__"); // Custom separator
// Now supports: "hover__bg-blue-500" instead of "hover:bg-blue-500"

When to customize:

  • When using a custom Tailwind configuration with different separator
  • To avoid conflicts with CSS-in-JS libraries that use colons

Prefix

Type: string (default: "")
Purpose: Adds a prefix to all Tailwind class names for namespacing.

var config = new TwConfig().Prefix("tw-");
// Supports: "tw-bg-blue-500", "tw-hover:bg-red-500"

When to customize:

  • When using Tailwind's prefix config option
  • To avoid conflicts with existing CSS frameworks
  • For component library isolation

Theme

Type: Dictionary<string, object>
Purpose: Defines theme values that can be referenced by class groups (colors, spacing, sizes, etc.).

var customTheme = new Dictionary<string, object>
{
    ["colors"] = new List<object> { /* custom color definitions */ },
    ["spacing"] = new List<object> { /* custom spacing values */ }
};
var config = new TwConfig().Theme(customTheme);

When to customize:

  • When extending Tailwind's default theme with custom values
  • When using custom color palettes or spacing scales
  • For design system integration

ClassGroups

Type: Dictionary<string, List<object>>
Purpose: Defines all available Tailwind class groups and their valid class patterns.

var customClassGroups = new Dictionary<string, List<object>>
{
    ["custom-size"] = new List<object>
    {
        new Dictionary<string, List<object>>
        {
            ["size"] = new List<object> { "tiny", "huge", "massive" }
        }
    }
};
var config = new TwConfig().ClassGroups(customClassGroups, extend: true);

When to customize:

  • Adding custom utility classes from Tailwind plugins
  • Supporting company-specific design tokens
  • Integrating with custom CSS frameworks

ConflictingClassGroups

Type: Dictionary<string, List<string>>
Purpose: Defines which class groups conflict with each other (e.g., p-4 conflicts with px-2).

var customConflicts = new Dictionary<string, List<string>>
{
    ["custom-margin"] = new List<string> { "margin", "margin-x", "margin-y" },
    ["custom-layout"] = new List<string> { "display", "position" }
};
var config = new TwConfig().ConflictingClassGroups(customConflicts, extend: true);

When to customize:

  • When adding custom utilities that should conflict with existing ones
  • For design system rules (e.g., preventing certain class combinations)
  • When creating semantic utility groups

ConflictingClassGroupModifiers

Type: Dictionary<string, List<string>>
Purpose: Defines additional conflicts that occur when classes have postfix modifiers (e.g., text-lg/tight conflicts with leading-*).

var modifierConflicts = new Dictionary<string, List<string>>
{
    ["font-size"] = new List<string> { "leading", "line-height" },
    ["custom-text"] = new List<string> { "tracking", "letter-spacing" }
};
var config = new TwConfig().ConflictingClassGroupModifiers(modifierConflicts);

When to customize:

  • When custom utilities should conflict only when used with postfix modifiers
  • For advanced typography or spacing utilities
  • When implementing complex design system rules

OrderSensitiveModifiers

Type: List<string>
Purpose: Specifies modifiers where order matters for CSS specificity (e.g., before:, after:, first-letter:).

var orderSensitive = new List<string> 
{ 
    "before", "after", "first-letter", "first-line", 
    "custom-pseudo", "custom-element" 
};
var config = new TwConfig().OrderSensitiveModifiers(orderSensitive);

When to customize:

  • When adding custom pseudo-element utilities
  • For CSS-in-JS integration where selector order matters
  • When implementing advanced styling patterns

Custom Implementation Examples

1. Design System Integration

// For a company design system with custom tokens
var designSystemConfig = new TwConfig()
    .Prefix("ds-")
    .Theme(new Dictionary<string, object>
    {
        ["colors"] = new List<object> 
        { 
            "brand-primary", "brand-secondary", "accent-blue", "accent-green" 
        },
        ["spacing"] = new List<object> 
        { 
            "micro", "tiny", "small", "medium", "large", "xlarge", "huge" 
        }
    })
    .ClassGroups(new Dictionary<string, List<object>>
    {
        ["brand-colors"] = new List<object>
        {
            new Dictionary<string, List<object>>
            {
                ["bg"] = new List<object> { "brand-primary", "brand-secondary" },
                ["text"] = new List<object> { "brand-primary", "brand-secondary" }
            }
        }
    }, extend: true)
    .ConflictingClassGroups(new Dictionary<string, List<string>>
    {
        ["brand-colors"] = new List<string> { "bg-color", "text-color" }
    }, extend: true);

var dstwMerge = new TwMerge(designSystemConfig);
var result = dstwMerge.Merge("ds-bg-brand-primary", "ds-bg-accent-blue");
// Result: "ds-bg-accent-blue" (brand colors conflict with regular colors)

2. Plugin Integration

// Supporting Tailwind plugins like @tailwindcss/typography
var typographyConfig = new TwConfig()
    .ClassGroups(new Dictionary<string, List<object>>
    {
        ["prose"] = new List<object>
        {
            "prose",
            new Dictionary<string, List<object>>
            {
                ["prose"] = new List<object> { "sm", "base", "lg", "xl", "2xl" }
            }
        },
        ["prose-colors"] = new List<object>
        {
            new Dictionary<string, List<object>>
            {
                ["prose"] = new List<object> 
                { 
                    "gray", "red", "yellow", "green", "blue", "indigo", "purple", "pink" 
                }
            }
        }
    }, extend: true)
    .ConflictingClassGroups(new Dictionary<string, List<string>>
    {
        ["prose"] = new List<string> { "prose-colors" }
    }, extend: true);

var proseTwMerge = new TwMerge(typographyConfig);
var result = proseTwMerge.Merge("prose", "prose-lg", "prose-gray", "prose-blue");
// Result: "prose-lg prose-blue"

3. Framework-Specific Setup

// For React/Blazor component libraries
var componentConfig = new TwConfig()
    .Separator("__")  // Avoid conflicts with CSS-in-JS
    .CacheSize(2000)  // Higher cache for component reuse
    .ConflictingClassGroupModifiers(new Dictionary<string, List<string>>
    {
        ["component-size"] = new List<string> { "padding", "margin", "gap" }
    })
    .OrderSensitiveModifiers(new List<string> 
    { 
        "before", "after", "hover", "focus", "active", "group-hover" 
    });

var componentTwMerge = new TwMerge(componentConfig);

4. Performance-Optimized Setup

// For high-frequency merging scenarios
var performanceConfig = new TwConfig()
    .CacheSize(5000)  // Large cache
    .Theme(minimalTheme)  // Reduced theme for faster lookups
    .ClassGroups(essentialClassGroups);  // Only required class groups

var fastTwMerge = new TwMerge(performanceConfig);

When to Use Custom Configurations

Extend Default Config When:

  • Adding custom utilities from Tailwind plugins
  • Supporting additional design tokens
  • Integrating with existing component libraries
  • Adding company-specific styling patterns

Override Default Config When:

  • Using a completely different design system
  • Heavy customization of Tailwind's default classes
  • Performance optimization for specific use cases
  • Legacy CSS framework migration

Configuration Best Practices:

  1. Always extend rather than replace when possible to maintain Tailwind compatibility
  2. Use consistent naming conventions for custom class groups
  3. Test conflict resolution thoroughly when adding custom conflicts
  4. Document custom configurations for team members
  5. Consider performance impact of large theme objects or class groups

Requirements

  • .NET 9.0 or higher

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Acknowledgements 🙏

This project is a C# adaptation of tailwind-merge originally developed by dcastil.

License

This project is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.7 354 5/29/2025
1.0.4 169 5/29/2025
1.0.2 137 5/29/2025
1.0.1 136 5/29/2025
1.0.1-g34e451f73e 135 5/29/2025