{"id":32331680,"url":"https://github.com/0xstern/tailwind-resolver","last_synced_at":"2025-10-23T19:54:17.070Z","repository":{"id":319273365,"uuid":"1078165216","full_name":"0xstern/tailwind-resolver","owner":"0xstern","description":"Resolve Tailwind theme variables into JavaScript objects. Supports Tailwind v4 with future-proof versioning.","archived":false,"fork":false,"pushed_at":"2025-10-19T01:48:11.000Z","size":436,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-19T02:28:43.277Z","etag":null,"topics":["canvas","chart","css-variables","parser","postcss","resolver","tailwind","tailwindcss","tailwindcss-v4","theme","theme-resolution","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/tailwind-resolver","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/0xstern.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["0xstern"],"custom":["https://x.com/mrstern_"]}},"created_at":"2025-10-17T09:58:50.000Z","updated_at":"2025-10-19T01:47:42.000Z","dependencies_parsed_at":"2025-10-19T02:28:55.012Z","dependency_job_id":null,"html_url":"https://github.com/0xstern/tailwind-resolver","commit_stats":null,"previous_names":["0xstern/tailwind-theme-extractor","0xstern/tailwind-theme-resolver"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/0xstern/tailwind-resolver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xstern%2Ftailwind-resolver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xstern%2Ftailwind-resolver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xstern%2Ftailwind-resolver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xstern%2Ftailwind-resolver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xstern","download_url":"https://codeload.github.com/0xstern/tailwind-resolver/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xstern%2Ftailwind-resolver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280683814,"owners_count":26372970,"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","status":"online","status_checked_at":"2025-10-23T02:00:06.710Z","response_time":142,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["canvas","chart","css-variables","parser","postcss","resolver","tailwind","tailwindcss","tailwindcss-v4","theme","theme-resolution","typescript"],"created_at":"2025-10-23T19:54:15.877Z","updated_at":"2025-10-23T19:54:17.064Z","avatar_url":"https://github.com/0xstern.png","language":"TypeScript","readme":"# Tailwind Theme Resolver\n\nResolve Tailwind CSS v4 theme variables into TypeScript types and runtime objects.\n\n\u003cp\u003e\n    \u003ca href=\"https://github.com/0xstern/tailwind-resolver/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/0xstern/tailwind-resolver/ci.yml?branch=main\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/0xstern/tailwind-resolver/releases\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/tailwind-resolver.svg\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/0xstern/tailwind-resolver/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/tailwind-resolver.svg\" alt=\"License\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://twitter.com/mrstern_\"\u003e\u003cimg alt=\"X (formerly Twitter) Follow\" src=\"https://img.shields.io/twitter/follow/mrstern_.svg?style=social\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Installation\n\n```bash\n# Bun\nbun add -D tailwind-resolver\n\n# pnpm\npnpm add -D tailwind-resolver\n\n# Yarn\nyarn add -D tailwind-resolver\n\n# npm\nnpm install -D tailwind-resolver\n```\n\n## Usage\n\n### Vite Plugin (Build-Time Generation)\n\n**1. Configure the plugin in `vite.config.ts`:**\n\n```typescript\nimport tailwindcss from '@tailwindcss/vite';\nimport { tailwindResolver } from 'tailwind-resolver/vite';\nimport { defineConfig } from 'vite';\n\nexport default defineConfig({\n  plugins: [\n    tailwindcss(),\n    tailwindResolver({\n      // Required: Path to your CSS input file (relative to Vite project root)\n      input: 'src/styles.css',\n\n      // Optional: Output directory for generated files (relative to Vite project root)\n      // Default: 'src/generated/tailwindcss' if src/ exists, otherwise 'generated/tailwindcss'\n      outputDir: 'src/generated/tailwindcss',\n\n      // Optional: Resolve @import statements recursively\n      // Default: true\n      resolveImports: true,\n\n      // Optional: Control what gets generated in the runtime file\n      // - false: No runtime file (types only)\n      // - true: Generate variants and selectors (optimized for production, excludes debug data)\n      // - object: Granular control - set files/variables to true for debugging\n      // Default: true\n      generateRuntime: {\n        variants: true, // Theme variants (default, dark, etc.)\n        selectors: true, // CSS selectors for variants\n        files: false, // Processed file list (debug only)\n        variables: false, // Raw CSS variables (debug only)\n        reports: {\n          conflicts: true, // Generate CSS conflict reports (default: true)\n          unresolved: true, // Generate unresolved variable reports (default: true)\n        },\n      },\n\n      // Optional: Include Tailwind CSS defaults from node_modules\n      // - true: Include all defaults (default)\n      // - false: Exclude all defaults\n      // - object: Granular control over which categories to include\n      // Default: true\n      includeTailwindDefaults: true,\n      // Or granular control:\n      // includeTailwindDefaults: {\n      //   colors: true,\n      //   spacing: true,\n      //   shadows: false,\n      //   radius: false,\n      // },\n\n      // Optional: Enable debug logging for troubleshooting\n      // Default: false\n      debug: false,\n    }),\n  ],\n});\n```\n\nThis generates files in `src/generated/tailwindcss/`:\n\n- `types.ts` - TypeScript interfaces\n- `theme.ts` - Runtime theme objects (if `generateRuntime: true`)\n- `index.ts` - Re-exports (if `generateRuntime: true`)\n- `conflicts.md` - Human-readable conflict report (if CSS conflicts detected and reports enabled)\n- `conflicts.json` - Machine-readable conflict report (if CSS conflicts detected and reports enabled)\n- `unresolved.md` - Human-readable unresolved variable report (if unresolved variables detected and reports enabled)\n- `unresolved.json` - Machine-readable unresolved variable report (if unresolved variables detected and reports enabled)\n\n**2. Use the generated theme in your code:**\n\n```typescript\nimport { dark, defaultTheme, tailwind } from './generated/tailwindcss';\n\n// Use the master tailwind object\nnew Chart(ctx, {\n  data: {\n    datasets: [\n      {\n        backgroundColor: [\n          tailwind.variants.default.colors.primary[500],\n          tailwind.variants.dark.colors.background,\n        ],\n      },\n    ],\n  },\n});\n\n// Or use individual variant exports for convenience\nconst primary = defaultTheme.colors.primary[500];\nconst darkBg = dark.colors.background;\n```\n\n### Runtime API (Dynamic Resolution)\n\n**1. Configure resolveTheme options:**\n\n```typescript\nimport { resolveTheme } from 'tailwind-resolver';\n\nconst result = await resolveTheme({\n  // Option 1: CSS file path (relative to cwd or absolute)\n  input: './src/styles.css',\n\n  // Option 2: Raw CSS content (alternative to input)\n  css: '@theme { --color-primary: blue; }',\n\n  // Optional: Base path for @import resolution (required when using css option)\n  basePath: process.cwd(),\n\n  // Optional: Resolve @import statements recursively\n  // Default: true\n  resolveImports: true,\n\n  // Optional: Include Tailwind CSS defaults from node_modules\n  // - true: Include all defaults (default)\n  // - false: Exclude all defaults\n  // - object: Granular control over which categories to include\n  // Default: true\n  includeTailwindDefaults: true,\n  // Or granular control:\n  // includeTailwindDefaults: {\n  //   colors: true,\n  //   spacing: true,\n  //   fonts: true,\n  //   shadows: false,\n  //   animations: false,\n  // },\n\n  // Optional: Enable debug logging\n  // Default: false\n  debug: false,\n});\n```\n\n**2. Use the resolved theme:**\n\n```typescript\n// With generated types for full type safety\n\nimport type { Tailwind } from './generated/tailwindcss';\n\nconst { variants, selectors, files, variables } = await resolveTheme\u003cTailwind\u003e({\n  input: './styles.css',\n});\n\n// Fully typed with autocomplete - same structure as generated constant\nconsole.log(variants.default.colors.primary[500]);\nconsole.log(variants.dark.colors.background);\nconsole.log(selectors.dark); // '[data-theme=\"dark\"]'\nconsole.log(files); // Array\u003cstring\u003e\nconsole.log(variables); // Array\u003cCSSVariable\u003e\n```\n\n### CLI\n\nGenerate types without a build tool:\n\n```bash\n# Bun\nbunx tailwind-resolver -i src/styles.css\n\n# pnpm\npnpm exec tailwind-resolver -i src/styles.css\n\n# Yarn\nyarn tailwind-resolver -i src/styles.css\n\n# npm\nnpx tailwind-resolver -i src/styles.css\n```\n\n**Options:**\n\n- `-i, --input \u003cpath\u003e` - CSS input file (required)\n- `-o, --output \u003cpath\u003e` - Output directory (default: auto-detected)\n- `-r, --runtime` - Generate runtime objects (default: true)\n- `--no-runtime` - Types only\n- `--include-defaults [categories]` - Include only specified Tailwind default categories (comma-separated)\n- `--exclude-defaults [categories]` - Include all except specified Tailwind default categories (comma-separated)\n- `--reports [categories]` - Generate only specified diagnostic reports (comma-separated: conflicts, unresolved)\n- `--exclude-reports [categories]` - Generate all except specified diagnostic reports (comma-separated)\n- `-d, --debug` - Enable debug mode (logging + include debug data in runtime)\n- `-h, --help` - Show help\n\n**Examples:**\n\n```bash\n# Include only colors and spacing from Tailwind defaults\nbunx tailwind-resolver -i src/styles.css --include-defaults colors,spacing\n\n# Exclude shadows and animations from Tailwind defaults\nbunx tailwind-resolver -i src/styles.css --exclude-defaults shadows,animations\n\n# Generate only conflict reports\nbunx tailwind-resolver -i src/styles.css --reports conflicts\n\n# Generate all reports except unresolved\nbunx tailwind-resolver -i src/styles.css --exclude-reports unresolved\n```\n\n## Theme Structure\n\n```typescript\n{\n  colors: {},           // --color-*\n  spacing: {},          // --spacing-* (callable: spacing(4) → 'calc(0.25rem * 4)')\n  fonts: {},            // --font-*\n  fontSize: {},         // --text-*\n  fontWeight: {},       // --font-weight-*\n  tracking: {},         // --tracking-*\n  leading: {},          // --leading-*\n  breakpoints: {},      // --breakpoint-*\n  containers: {},       // --container-*\n  radius: {},           // --radius-*\n  shadows: {},          // --shadow-*\n  insetShadows: {},     // --inset-shadow-*\n  dropShadows: {},      // --drop-shadow-*\n  textShadows: {},      // --text-shadow-*\n  blur: {},             // --blur-*\n  perspective: {},      // --perspective-*\n  aspect: {},           // --aspect-*\n  ease: {},             // --ease-*\n  animations: {},       // --animate-*\n  defaults: {},         // --default-*\n  keyframes: {}         // @keyframes\n}\n```\n\n### Dynamic Spacing Helper\n\nThe `spacing` property is special - it's both an object with static values AND a callable function for dynamic calculations:\n\n```typescript\nimport { defaultTheme, dark } from './generated/tailwindcss';\n\n// Static spacing values (defined in your CSS)\ndefaultTheme.spacing.xs;      // '0.75rem'\ndefaultTheme.spacing.base;    // '0.25rem'\n\n// Dynamic spacing calculations (matches Tailwind's behavior)\ndefaultTheme.spacing(4);      // 'calc(0.25rem * 4)' → 1rem\ndefaultTheme.spacing(16);     // 'calc(0.25rem * 16)' → 4rem\ndefaultTheme.spacing(-2);     // 'calc(0.25rem * -2)' → -0.5rem\n\n// Use in styles\n\u003cdiv style={{\n  padding: defaultTheme.spacing(4),        // Same as Tailwind's p-4\n  margin: defaultTheme.spacing(-2),        // Same as Tailwind's -m-2\n  width: defaultTheme.spacing(64),         // Same as Tailwind's w-64\n  gap: defaultTheme.spacing(2),            // Same as Tailwind's gap-2\n}} /\u003e\n\n// Works with all variants\ndark.spacing(8);              // Uses dark theme's spacing base (or falls back to default)\n```\n\n**Why this exists:** Tailwind generates utilities like `p-4`, `m-8`, `w-16` using `calc(var(--spacing) * N)`. This helper replicates that behavior for runtime use.\n\n**Tailwind utilities that use spacing calculations:**\n\n- `inset-\u003cn\u003e`, `m-\u003cn\u003e`, `p-\u003cn\u003e`, `gap-\u003cn\u003e`\n- `w-\u003cn\u003e`, `h-\u003cn\u003e`, `min-w-\u003cn\u003e`, `max-w-\u003cn\u003e`, `min-h-\u003cn\u003e`, `max-h-\u003cn\u003e`\n- `indent-\u003cn\u003e`, `border-spacing-\u003cn\u003e`, `scroll-m-\u003cn\u003e`\n\n**Note:** If your theme doesn't define `--spacing-base`, the spacing helper won't be generated. Define spacing in your CSS to enable this feature.\n\n\u003e **Other CSS variables:** Tailwind uses different CSS variables for different utilities:\n\u003e\n\u003e - Layout properties like `columns` and `flex-basis` use `--container-*` values\n\u003e - Transform properties like `translate-x` and `translate-y` use `--tw-translate-*` variables\n\u003e - Animation properties use `--default-*` meta variables\n\u003e\n\u003e For a complete list of which CSS variables Tailwind uses for each utility, refer to the [Tailwind CSS documentation](https://tailwindcss.com/docs).\n\n## Theme Variants\n\n```css\n@theme {\n  --color-background: #ffffff;\n}\n\n[data-theme='dark'] {\n  --color-background: #1f2937;\n}\n```\n\n**Usage:**\n\n```typescript\nimport {\n  dark,\n  defaultTheme,\n  selectors,\n  tailwind,\n} from './generated/tailwindcss';\n\n// All values are fully typed\nconsole.log(tailwind.variants.default.colors.background); // '#ffffff'\nconsole.log(tailwind.variants.dark.colors.background); // '#1f2937'\nconsole.log(tailwind.selectors.dark); // \"[data-theme='dark']\"\n\n// Or use individual exports\nconsole.log(defaultTheme.colors.background); // '#ffffff'\nconsole.log(dark.colors.background); // '#1f2937'\nconsole.log(selectors.dark); // \"[data-theme='dark']\"\n```\n\n## Type Safety\n\nThe generated `types.ts` exports a `Tailwind` interface that provides full type safety for both the generated constant and the runtime API:\n\n```typescript\nimport type { Tailwind } from './generated/tailwindcss';\n\nimport { resolveTheme, tailwind } from './generated/tailwindcss';\n\n// Generated constant - fully typed\ntailwind.variants.default.colors.primary[500]; // ✓ Type-safe\ntailwind.variants.dark.colors.background; // ✓ Type-safe\ntailwind.selectors.dark; // ✓ Type-safe\n\n// Runtime API - same structure, same types\nconst result = await resolveTheme\u003cTailwind\u003e({\n  input: './theme.css',\n});\n\nresult.variants.default.colors.primary[500]; // ✓ Type-safe\nresult.variants.dark.colors.background; // ✓ Type-safe\nresult.selectors.dark; // ✓ Type-safe\n```\n\nAutocomplete works automatically when the output directory is in `tsconfig.json` includes.\n\n## Report Generation\n\nThe resolver can generate diagnostic reports to help you understand and troubleshoot your theme configuration.\n\n### Controlling Report Generation\n\nReports are enabled by default but can be controlled via configuration:\n\n**Vite Plugin:**\n\n```typescript\ntailwindResolver({\n  input: 'src/styles.css',\n  generateRuntime: {\n    reports: false, // Disable all reports\n  },\n});\n\n// Or granular control\ntailwindResolver({\n  input: 'src/styles.css',\n  generateRuntime: {\n    reports: {\n      conflicts: true, // Enable conflict reports\n      unresolved: false, // Disable unresolved variable reports\n    },\n  },\n});\n```\n\n**CLI:**\n\n```bash\n# Disable all reports\nbunx tailwind-resolver -i src/styles.css --no-reports\n\n# Disable only conflict reports\nbunx tailwind-resolver -i src/styles.css --no-conflict-reports\n\n# Disable only unresolved variable reports\nbunx tailwind-resolver -i src/styles.css --no-unresolved-reports\n```\n\n## CSS Conflict Detection\n\nThe resolver automatically detects when CSS rules override CSS variables and ensures the runtime theme object matches actual rendered styles.\n\n### Problem\n\nReal-world CSS files often contain both CSS variables AND direct CSS rules:\n\n```css\n.theme-mono {\n  --radius-lg: 0.45em; /* CSS variable */\n\n  .rounded-lg {\n    border-radius: 0; /* CSS rule - overrides the variable! */\n  }\n}\n```\n\nWithout detection, the runtime theme would incorrectly report `radius.lg: \"0.45em\"` when the actual rendered value is `\"0\"`.\n\n### Solution\n\nThe resolver:\n\n1. **Detects all conflicts** between CSS rules and variables\n2. **Applies high-confidence overrides** automatically for simple cases\n3. **Reports complex cases** in `conflicts.md` for manual review\n\n### Conflict Reports\n\nWhen conflicts are detected, two report files are generated:\n\n**`conflicts.md`** - Human-readable report with:\n\n- Summary of total/resolved/pending conflicts\n- Auto-resolved conflicts (applied to theme)\n- Conflicts requiring manual review\n- Context-specific recommendations\n\n**`conflicts.json`** - Machine-readable format for CI/CD integration\n\n### Terminal Output\n\nNon-intrusive single-line notification:\n\n```\n✓ Theme types generated successfully\n\nGenerated files:\n  - src/generated/tailwindcss/types.ts\n  - src/generated/tailwindcss/theme.ts\n  - src/generated/tailwindcss/index.ts\n\n⚠  12 CSS conflicts detected (see src/generated/tailwindcss/conflicts.md)\n```\n\n### Confidence Levels\n\n**High Confidence** (auto-applied):\n\n- Static values (e.g., `border-radius: 0`)\n- No pseudo-classes or media queries\n- Simple selectors\n\n**Medium/Low Confidence** (manual review):\n\n- Dynamic values (e.g., `calc()`, `var()`)\n- Pseudo-classes (`:hover`, `:focus`)\n- Media query nesting\n- Complex selectors\n\nHigh-confidence overrides ensure your runtime theme matches actual rendered styles.\n\n## Unresolved Variable Detection\n\nThe resolver automatically detects CSS variables with `var()` references that couldn't be resolved, helping identify variables requiring external injection or definition.\n\n### Problem\n\nReal-world CSS often references variables injected at runtime or provided externally:\n\n```css\n@theme {\n  --font-sans: var(--font-inter); /* Injected by Next.js */\n  --color-accent: var(--tw-primary); /* Tailwind plugin variable */\n}\n```\n\n### Solution\n\nThe resolver:\n\n1. **Detects unresolved `var()` references** after variable resolution\n2. **Categorizes by likely cause** (external, self-referential, unknown)\n3. **Generates detailed reports** in `unresolved.md` and `unresolved.json`\n\n### Unresolved Variable Reports\n\nWhen unresolved variables are detected, two report files are generated:\n\n**`unresolved.md`** - Human-readable report with:\n\n- Summary of total unresolved variables by cause\n- Detailed list grouped by cause with context (variable name, source, selector)\n- Actionable recommendations for each category\n- Fallback values if specified\n\n**`unresolved.json`** - Machine-readable format for CI/CD integration\n\n### Terminal Output\n\n```\nℹ  8 unresolved variables detected (see src/generated/tailwindcss/unresolved.md)\n```\n\n### Variable Categories\n\n**Unknown** - Variables requiring review:\n\n- May need to be defined in your theme\n- Or verified to be loaded externally\n\n**External** - Variables from external sources:\n\n- Tailwind plugins (detected by `--tw-*` prefix)\n- Runtime injection (Next.js fonts, framework variables)\n- External stylesheets\n\n**Self-referential** - Variables intentionally left unresolved:\n\n- Variables like `--font-sans: var(--font-sans)`\n- Intentionally skipped to use Tailwind defaults\n\n## Disabling Default Theme Values with `initial`\n\nRemove unwanted Tailwind defaults by setting theme variables to `initial` in `@theme` blocks, matching the official Tailwind CSS v4 behavior ([docs](https://tailwindcss.com/docs/colors#disabling-default-colors)).\n\n```css\n@theme {\n  /* Remove specific theme properties */\n  --color-lime-*: initial;\n  --spacing-4: initial;\n  --radius-lg: initial;\n\n  /* Remove entire categories */\n  --color-*: initial;\n  --spacing-*: initial;\n\n  /* Custom values are always preserved */\n  --color-primary-500: #3b82f6;\n}\n```\n\n### Key Features\n\n- **Works for all theme properties** - Colors, spacing, fonts, shadows, radius, etc.\n- **Supports wildcards** - Use `*` to match multiple values (`--color-lime-*`, `--color-*`)\n- **Preserves custom values** - Only removes Tailwind defaults, never your custom theme\n- **Highest priority** - Takes precedence over `includeTailwindDefaults` configuration\n- **Supports `@theme` and `@theme inline`** blocks\n\n### Relationship with `includeTailwindDefaults`\n\nUse both together for maximum control:\n\n```typescript\nconst result = await resolveTheme({\n  css: `\n    @theme {\n      --color-lime-*: initial;\n      --color-fuchsia-*: initial;\n      --spacing-4: initial;\n    }\n  `,\n  includeTailwindDefaults: {\n    colors: true, // Include all colors...\n    spacing: true, // Include all spacing...\n    shadows: false, // Exclude shadows\n  },\n});\n\n// Result:\n// - Colors: All defaults EXCEPT lime and fuchsia (removed by initial)\n// - Spacing: All defaults EXCEPT spacing.4 (removed by initial)\n// - Shadows: Empty (excluded by config)\n```\n\n| Configuration                               | Result                                       |\n| ------------------------------------------- | -------------------------------------------- |\n| `includeTailwindDefaults: true`             | All defaults included                        |\n| `includeTailwindDefaults: false`            | No defaults included                         |\n| `includeTailwindDefaults: { colors: true }` | Only color defaults included                 |\n| `initial` in CSS                            | Removes specific defaults (highest priority) |\n\n### Use Cases\n\n**1. Reduce bundle size** - Remove unused defaults:\n\n```css\n@theme {\n  --color-lime-*: initial;\n  --color-fuchsia-*: initial;\n  --color-pink-*: initial;\n}\n```\n\n**2. Prevent conflicts** - Remove defaults that clash with your brand:\n\n```css\n@theme {\n  --color-blue-*: initial;\n  --color-primary-500: #1e40af; /* Custom brand blue */\n}\n```\n\n**3. Minimal theme** - Start from scratch:\n\n```css\n@theme {\n  --color-*: initial;\n\n  --color-foreground: #000;\n  --color-background: #fff;\n  --color-primary-500: #3b82f6;\n}\n```\n\n**4. Platform-specific themes**:\n\n```typescript\n// Mobile - minimal palette\nconst mobile = await resolveTheme({\n  css: '@theme { --color-*: initial; --color-primary-500: blue; }',\n  includeTailwindDefaults: { spacing: true },\n});\n\n// Desktop - full palette\nconst desktop = await resolveTheme({\n  css: '@theme { --color-primary-500: blue; }',\n  includeTailwindDefaults: true,\n});\n```\n\n## Theme Overrides\n\nApply custom theme value overrides programmatically to fix unresolved variables or conflicts without modifying CSS files.\n\n### When to Use Overrides\n\n- **Inject external variables**: Provide values for variables from Next.js, plugins, or external sources\n- **Fix variant-specific values**: Override theme properties for dark mode or custom themes\n- **Global customization**: Apply consistent values across all variants\n- **Quick prototyping**: Test theme changes without editing CSS\n\n### Configuration\n\n**Vite Plugin:**\n\n```typescript\ntailwindResolver({\n  input: 'src/styles.css',\n  overrides: {\n    // Override default theme\n    default: {\n      'fonts.sans': 'Inter, sans-serif',\n      'radius.lg': '0.5rem',\n    },\n\n    // Override dark variant\n    dark: {\n      'colors.background': '#000000',\n    },\n\n    // Apply to all variants (wildcard)\n    '*': {\n      'fonts.mono': 'JetBrains Mono, monospace',\n    },\n  },\n});\n```\n\n**Runtime API:**\n\n```typescript\nconst result = await resolveTheme({\n  input: './styles.css',\n  overrides: {\n    default: {\n      'colors.primary.500': '#custom-blue',\n    },\n  },\n});\n```\n\n### Syntax Options\n\n**Flat Notation** (dot-separated paths):\n\n```typescript\noverrides: {\n  'default': {\n    'colors.primary.500': '#custom-blue',\n    'radius.lg': '0.5rem',\n    'fonts.sans': 'Inter, sans-serif'\n  }\n}\n```\n\n**Nested Notation**:\n\n```typescript\noverrides: {\n  'default': {\n    colors: {\n      primary: {\n        500: '#custom-blue'\n      }\n    },\n    radius: {\n      lg: '0.5rem'\n    }\n  }\n}\n```\n\n**Mix and Match**:\n\n```typescript\noverrides: {\n  'default': {\n    'colors.primary.500': '#custom-blue',\n    radius: { lg: '0.5rem' }\n  }\n}\n```\n\n### Selector Matching\n\nOverrides support multiple selector patterns:\n\n```typescript\noverrides: {\n  // Variant name (use camelCase for multi-word variants)\n  'dark': { 'colors.background': '#000' },\n  'themeInter': { 'fonts.sans': 'Inter, sans-serif' },  // .theme-inter → themeInter\n\n  // CSS selector (verbose, but works)\n  '[data-theme=\"dark\"]': { 'colors.background': '#000' },\n\n  // Default theme\n  'default': { 'radius.lg': '0.5rem' },\n  'base': { 'radius.lg': '0.5rem' }, // Alias for 'default'\n\n  // All variants (wildcard)\n  '*': { 'fonts.sans': 'Inter, sans-serif' }\n}\n```\n\n**Important:** Variant names are automatically converted from kebab-case to camelCase:\n\n- CSS: `.theme-inter` → Override key: `'themeInter'`\n- CSS: `.theme-noto-sans` → Override key: `'themeNotoSans'`\n- CSS: `.dark` → Override key: `'dark'` (no conversion needed)\n\nUse the exact camelCase variant names from your generated types for reliable matching.\n\n### Detailed Control\n\nUse object notation for fine-grained control:\n\n```typescript\noverrides: {\n  'dark': {\n    'radius.lg': {\n      value: '0',\n      force: true,        // Apply even for low-confidence conflicts\n      resolveVars: false  // Skip variable resolution (post-resolution only)\n    }\n  }\n}\n```\n\n### Common Use Cases\n\n**1. Injecting External Variables**\n\nFix unresolved variables from Next.js, plugins, or external sources:\n\n```typescript\noverrides: {\n  'default': {\n    'fonts.sans': 'var(--font-inter)',  // Next.js font\n    'colors.primary': 'var(--tw-primary)' // Tailwind plugin\n  }\n}\n```\n\n**2. Variant-Specific Overrides**\n\nCustomize individual theme variants:\n\n```typescript\noverrides: {\n  'dark': {\n    'colors.background': '#000000',\n    'colors.foreground': '#ffffff'\n  },\n  'compact': {\n    'radius.lg': '0',\n    'spacing.base': '0.125rem'\n  }\n}\n```\n\n**3. Global Overrides**\n\nApply consistent values across all variants:\n\n```typescript\noverrides: {\n  '*': {\n    'fonts.sans': 'Inter, -apple-system, BlinkMacSystemFont, sans-serif',\n    'fonts.mono': 'JetBrains Mono, Consolas, monospace'\n  }\n}\n```\n\n**4. Prototyping Without CSS Changes**\n\nQuickly test theme variations:\n\n```typescript\noverrides: {\n  'default': {\n    'colors.primary.500': '#ff6b6b',\n    'radius.lg': '1rem'\n  }\n}\n```\n\n### How It Works\n\nThe override system uses a two-phase approach:\n\n1. **Pre-resolution** (Variable Injection)\n   - Injects synthetic CSS variables before variable resolution\n   - Allows overrides to participate in `var()` resolution\n   - Applied to: `'default'`, `'base'`, `'*'` selectors\n\n2. **Post-resolution** (Theme Mutation)\n   - Directly mutates resolved theme objects after building\n   - Overrides final computed values\n   - Applied to: all selector types\n\nThis hybrid approach ensures maximum flexibility and correct variable resolution.\n\n### Debug Mode\n\nEnable debug logging to see override activity:\n\n```typescript\ntailwindResolver({\n  input: 'src/styles.css',\n  debug: true,\n  overrides: {\n    default: { 'radius.lg': '0.5rem' },\n  },\n});\n```\n\nOutput:\n\n```\n[Overrides] Injected variable: --radius-lg = 0.5rem\n[Overrides] Injected 1 variables for 'default'\n[Overrides] Applied to 'default': radius.lg = 0.5rem\n[Overrides] Summary for 'default': 1 applied, 0 skipped\n```\n\n## Debugging\n\nEnable debug mode to see warnings for failed imports:\n\n**Vite:**\n\n```typescript\ntailwindResolver({ input: 'src/styles.css', debug: true });\n```\n\n**CLI:**\n\n```bash\nbunx tailwind-resolver -i src/styles.css --debug\n# or: pnpm exec / yarn / npx\n```\n\n**Runtime:**\n\n```typescript\nresolveTheme({ input: './theme.css', debug: true });\n```\n\n**Output:**\n\n```\n[Tailwind Theme Resolver] Failed to resolve import: ./components/theme.css\n  Resolved path: /Users/you/project/src/components/theme.css\n  Error: ENOENT: no such file or directory\n```\n\nFailed imports are silently skipped by design. Enable debug mode only when troubleshooting.\n\n## Examples\n\n### Chart.js\n\n```typescript\nimport { tailwind } from './generated/tailwindcss';\n\nnew Chart(ctx, {\n  data: {\n    datasets: [\n      {\n        // Fully typed colors with autocomplete\n        backgroundColor: [\n          tailwind.variants.default.colors.primary[500],\n          tailwind.variants.dark.colors.secondary[500],\n        ],\n      },\n    ],\n  },\n});\n```\n\n### Canvas\n\n```typescript\nimport { defaultTheme } from './generated/tailwindcss';\n\n// All properties are type-safe\nctx.fillStyle = defaultTheme.colors.background;\nctx.font = `${defaultTheme.fontSize.xl.size} ${defaultTheme.fonts.display}`;\n```\n\n### Dynamic Themes\n\n```typescript\nimport { tailwind } from './generated/tailwindcss';\n\n// Theme switching with full type safety\nconst currentTheme = isDark\n  ? tailwind.variants.dark\n  : tailwind.variants.default;\nchartInstance.data.datasets[0].backgroundColor =\n  currentTheme.colors.primary[500];\nchartInstance.update();\n```\n\n## TypeScript Configuration\n\nEnsure the output directory is included in `tsconfig.json`:\n\n```json\n{\n  \"include\": [\"src/**/*\"],\n  \"compilerOptions\": {\n    \"skipLibCheck\": true\n  }\n}\n```\n\n## Requirements\n\n- Node.js \u003e= 18 or Bun \u003e= 1.0\n- TypeScript \u003e= 5.0 (for type generation)\n- Vite \u003e= 5.0 (for Vite plugin)\n\n## License\n\nMIT\n\n## Contributing\n\nIssues and pull requests welcome on [GitHub](https://github.com/0xstern/tailwind-resolver).\n\n## Support\n\nIf you find this helpful, follow me on X [@mrstern\\_](https://x.com/mrstern_)\n","funding_links":["https://github.com/sponsors/0xstern","https://x.com/mrstern_"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xstern%2Ftailwind-resolver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xstern%2Ftailwind-resolver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xstern%2Ftailwind-resolver/lists"}