Tailwind → VelinStyle migrate 1.4.0
Automated, honest migration for Tailwind v3/v4 projects. Dry-run by default. Unresolved tokens are never silently rewritten. This is not a Fake-1:1 claim. Deutsch
@birdapi/velinstyle) → optional Compatibility (@birdapi/velinstyle-tailwind) → optional Heuristic (--heuristic palette-roles).
Compatibility is not a second design system.
Prerequisites
- Node.js 18+
- Work on a copy of your site (never overwrite production without backup)
- Optional: install
@birdapi/velinstyle-tailwindwhen using--compat tailwind
Three CLI modes
# Core-only (default dry-run)
velinstyle migrate tailwind ./my-project
# Core + Compatibility catalog
velinstyle migrate tailwind ./my-project --compat tailwind
# Core + Compat + opt-in palette→role heuristic
velinstyle migrate tailwind ./my-project --compat tailwind --heuristic palette-roles
# Apply Mapped rewrites only
velinstyle migrate tailwind ./my-project --write
velinstyle migrate rollback ./my-project| Mode | Catalog | Notes |
|---|---|---|
| Core-only | Core only | Compat classes stay unresolved / suggested |
--compat tailwind | Core ∪ Compat | Loads @birdapi/velinstyle-tailwind |
--heuristic palette-roles | Core ∪ Compat + map-only roles | Semantic approximation — not visual 1:1 |
Dry-run (default)
- Detects Tailwind (v3/v4 CSS-first included)
- Analyzes static
class/className/@apply - Writes
.velin/migration/last-dry-run.json(+.md) - Does not change source files or create a snapshot
Apply (--write / --apply)
- Snapshot under
.velin/migration/snapshots/<id>/ - Rewrites Mapped tokens only
- Unresolved / Warning tokens stay untouched
- Tailwind dependencies are never auto-removed
Class examples (with Compat)
| Tailwind | VelinStyle Compat |
|---|---|
px-4 | velin-px-4 |
w-4 | velin-w-4 |
grid-cols-3 | velin-grid-cols-3 |
flex-1 | velin-flex-1 |
rounded-md | velin-rounded-md |
space-y-4 | velin-space-y-4 |
bg-emerald-500/10 | velin-bg-emerald-500-10 (slash-opacity) |
Slash-opacity
- Tier 1: plain
bg/text/border+/N→velin-{prop}-{color}-{N}viacolor-mix() - Tier 2:
from/via/to/shadow/ring/outline/divide+/N - Requires
--compat tailwind - State-prefixed slash forms (e.g.
hover:bg-…/10) stay unresolved
Responsive Compat
Supported wrappers: sm, md, lg, xl → velin-{bp}-* when the base class is in the catalog.
2xl is not supported and stays unresolved. This is not full Tailwind breakpoint parity.
Palette-role heuristic
Opt-in only: --heuristic palette-roles. Maps palette solids to existing Core semantic roles when a safe target exists:
- emerald → success
- red → danger
- amber → warning
- blue / cyan → info
- zinc / slate → surface / muted
Heuristic ≠ 1:1 color conversion. Palette without a Core target stays unresolved.
Reports
Dry-run JSON includes among others:
compatibilityPackage—absent|used|suggestedheuristic— requested id + honesty notedynamicAttrsSkipped— dynamicclassName/cn()count (own KPI, not in Coverage denominator)compat.requested,compat.root,compat.catalogSize,compat.gapCounttier2SlashOpacity,paletteRoleList- Mapping reasons e.g.
catalog-1to1,compat-slash-opacity,compat-slash-opacity-tier2,palette-role,breakpoint:sm, …
Pilot measurement (velisch.info copy)
velisch.info copy), not “VelinStyle supports X% of Tailwind.”
| Metric | Value |
|---|---|
| Detected | 806 |
| Mapped (Compat + heuristic) | 559 |
| CoverageMapped% | 69.4% |
| Warnings | 74 |
| Unresolved | 173 |
| DynamicAttrsSkipped | 351 (separate KPI) |
| Compat Catalog | 2736 |
| Core Catalog | 1427 |
| Tests (Intelligence + migrate) | 94 |
| Tests (+ release-sync) | 102 |
| Historical Core-only baseline | 162 / 806 = 20.1% (historical) |
An ≥80% gate was not reached — and must not be claimed. Realistic static ceiling without new State / Arbitrary / Theme / Dynamic engines: about 70–71%. Deliberate architecture choice in 1.4.x.
Migration Intelligence
After migrate analysis, residuals are structured as 23 User Actions and 6 Strategy Blocks. Acceptance, Rewrite Manifest, Preflight, Dry-Run, and Apply-Gate are available — but residual rewrites require an explicit mapping.
source→target mappings in the current pilot.
Intelligence does not invent targets. Details: Migration Intelligence.
P1 --write still applies only Catalog-Mapped tokens. That path is separate from Intelligence residual Apply.