tw2x 1.0.3
dotnet tool install --global tw2x --version 1.0.3
dotnet new tool-manifest
dotnet tool install --local tw2x --version 1.0.3
#tool dotnet:?package=tw2x&version=1.0.3
nuke :add-package tw2x --version 1.0.3
🌀 tailwind2xaml (tw2x)
Convert Tailwind CSS theme color definitions (OKLCH) into a XAML ResourceDictionary, ready for use in .NET MAUI, WPF, or UWP projects.
Why?
Design once, use everywhere! Reuse your Tailwind palette seamlessly in your XAML-based apps without manual hex conversions.
Features
- Converts Tailwind OKLCH colors to HEX (including alpha, e.g.
oklch(1 0 0 / 10%)→#1AFFFFFF) - Resolves
var(...)references — including chained references andvar(--x, fallback)— so semantic themes (e.g. shadcn) convert fully instead of producing empty colors - Emits two layers in one dictionary: a palette of raw
<Color>resources and a semantic set of<SolidColorBrush>resources that reference the palette viaDynamicResource - Supports black/white and fallback values
- Easy CLI usage
- Works cross-platform (Windows, macOS, Linux)
Installation
dotnet tool install -g tw2x
Usage
tw2x <inputFile> [outputFile]
Arguments
<inputFile>— Required. Path to your Tailwind theme file (containing @theme { ... } block).[outputFile]— Optional. Defaults to Colors.xaml next to your input file.
Optional target framework
tw2x theme.txt --target maui
tw2x theme.txt MyColors.xaml -t avalonia
Options for --target:
maui- .NET MAUI (default)wpf- WPFavalonia- Avalonia UIuwp- UWPuno- Uno Platform
Examples
tw2x tailwind.css
This will read tailwind.css, extract the theme colors, convert them to HEX, and output a Colors.xaml file in the same directory.
tw2x tailwind.css myColors.xaml
This will read tailwind.css and output the converted colors to myColors.xaml.
Output: palette + semantic brushes
The generated dictionary is split into two layers:
- Palette — the raw colors, as
<Color>resources. Each color is a distinct, individually-tweakable slot. Two roles that happen to share the same value (e.g.PrimaryandRing) get separate palette entries so you can retune one without affecting the other. - Semantic brushes — one
<SolidColorBrush>per theme role, named<Role>Brush, referencing a palette color viaDynamicResource.
Bind your UI to the brushes, not the palette colors. Because they use DynamicResource, swapping a palette <Color> at runtime retints every brush that references it — which is what makes runtime theme/palette switching work. (Resolution is by key at runtime, so the ordering of the two sections doesn't matter.)
When the input has a semantic layer (--color-primary: var(--primary)), the brush points at the named base color. When the input is a flat palette with no var() references (e.g. a raw Tailwind scale), each color gets a self-named brush (Red500 → Red500Brush).
Example generated XAML
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Color x:Key="Primary">#F97D14</Color>
<Color x:Key="Ring">#F97D14</Color>
<Color x:Key="Border">#1AFFFFFF</Color>
...
<SolidColorBrush x:Key="PrimaryBrush" Color="{DynamicResource Primary}" />
<SolidColorBrush x:Key="RingBrush" Color="{DynamicResource Ring}" />
<SolidColorBrush x:Key="BorderBrush" Color="{DynamicResource Border}" />
...
</ResourceDictionary>
Consume a brush like any other resource:
<Border Background="{DynamicResource PrimaryBrush}" />
Contributing
PRs and ideas welcome! Open an issue or submit a PR to suggest features or improvements.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
This package has no dependencies.