---
title: "tailwindcss-obfuscator"
description: "Outil Open Source d'obfuscation CSS pour Tailwind CSS v3 & v4"
locale: "fr"
canonical: "https://portfolio.josedacosta.info/fr/realisations/tailwindcss-obfuscator"
source: "https://portfolio.josedacosta.info/fr/realisations/tailwindcss-obfuscator.md"
html_source: "https://portfolio.josedacosta.info/fr/realisations/tailwindcss-obfuscator"
author: "José DA COSTA"
date: "2025"
type: "achievement"
slug: "tailwindcss-obfuscator"
tags: ["TypeScript 5.7", "Node.js 18+", "TurboRepo", "pnpm", "tsup", "Vitest", "Babel", "PostCSS", "Commander.js", "VitePress", "magic-string"]
generated_at: "2026-05-26T15:39:21.351Z"
---

# tailwindcss-obfuscator

Outil Open Source d'obfuscation CSS pour Tailwind CSS v3 & v4

**Date:** Déc 2025 - Jan 2026  
**Durée:** ~6 semaines  
**Rôle:** Créateur & Lead Technique  
**Technologies:** TypeScript 5.7, Node.js 18+, TurboRepo, pnpm, tsup, Vitest, Babel, PostCSS, Commander.js, VitePress, magic-string

## Présentation du projet

_Protéger la propriété intellectuelle CSS dans l'écosystème Tailwind_

### Qu'est-ce que tailwindcss-obfuscator ?

### Le problème

### Bonus : un HTML plus léger

### Capacités principales

### Analyse statique

Extraction de classes agnostique au framework depuis HTML, JSX, Vue SFC, Svelte, Astro, Qwik et CSS

### Double parsing

Deux modes de transformation : regex rapide pour les cas simples et AST (Abstract Syntax Tree) précis via Babel + PostCSS pour les scénarios complexes

### Plugins universels

5 plugins bundler (Vite, Webpack, Rollup, esbuild, module Nuxt) partageant le même moteur central

### Tailwind v3 & v4

Premier outil d'obfuscation compatible avec Tailwind v4 (moteur Rust/Oxide) - détection automatique de version

### Utilisateurs cibles

- **Concrètement**, l'outil intervient au moment du build : les classes Tailwind lisibles utilisées dans le code source (`bg-blue-500 hover:bg-blue-700`) deviennent des identifiants courts et opaques (`tw-a tw-b`) dans le HTML et le CSS livrés au navigateur. Le résultat visuel reste identique, mais l'empreinte textuelle du design system disparaît.
- L'outil fonctionne via un **pipeline en trois phases** : extraction des classes Tailwind depuis les fichiers source (HTML, JSX, TSX, Vue, Svelte, Astro, Qwik, CSS), génération de mapping déterministe ou aléatoire, et remplacement systématique dans le CSS compilé et les templates.
- Pour s'affranchir de cette dépendance aux internals, tailwindcss-obfuscator mise sur l'**analyse statique** : plutôt que de patcher le moteur Tailwind, l'outil scanne directement les fichiers source du projet pour y repérer les classes utilisées. Cette indépendance explique pourquoi il supporte sans rupture les versions v3 et v4, là où le concurrent <a href="https://github.com/sonofmagic/tailwindcss-mangle" target="_blank" rel="noopener noreferrer" class="text-primary underline">unplugin-tailwindcss-mangle</a> est resté bloqué en v3.

### Développeurs frontend déployant Tailwind CSS en production

- Développeurs frontend déployant Tailwind CSS en production
- Agences de design protégeant leur design system
- Éditeurs SaaS voulant compliquer la copie de leur interface
- Créateurs de bibliothèques de composants commercialisant des UI kits

Un **package npm open source** qui obfusque les noms de classes CSS générés par Tailwind CSS, transformant les noms lisibles comme `bg-blue-500` en identifiants courts et opaques au moment du build.

Le seul concurrent existant repose sur le patching des internals de Tailwind - une approche qui **ne fonctionne plus avec Tailwind v4** (réécrit en Rust/Oxide). Aucune solution compatible v4 n'existait sur le marché.

Au-delà de la protection intellectuelle, l'obfuscation **allège significativement le poids du HTML**. L'approche **utility-first** de Tailwind génère une **forte répétition des mêmes chaînes de classes** dans le corps des pages (ex : `bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded` dupliqué sur des centaines d'éléments). En compactant ces classes en identifiants courts comme `tw-a tw-b`, l'outil **réduit la taille du HTML transféré au navigateur** - un gain particulièrement sensible sur les **pages longues**, le **streaming SSR** et les **payloads mobile**, avec un impact direct sur le **temps de chargement**.

## Objectifs, Contexte & Risques

_Positionnement stratégique dans une niche sans solution compatible v4_

### Empêcher la copie triviale des design systems depuis les DevTools

### 1 247 octets réduits à 312 octets sur un échantillon réel

### React, Next.js, Vue, Nuxt, SvelteKit, Astro, Remix, Qwik, Solid.js, HTML

### Aucun overhead en production - l'obfuscation s'effectue exclusivement au build

### Contexte

### Enjeux

### Faux négatif d'extraction

Lorsqu'un extracteur laisse échapper une classe présente dans le CSS, le style correspondant disparaît sans erreur ni log : c'est précisément le scénario évoqué dans les enjeux. Atténuation par **295 tests**, **10 apps de test** et **extracteurs spécialisés par framework**.

### Incompatibilité version Tailwind

Les **futures mises à jour Tailwind** pourraient casser les patterns d'extraction. Atténuation par **auto-détection** et **architecture modulaire**.

### Limitation classes dynamiques

Les **classes construites au runtime** ne peuvent pas être extraites statiquement. Documenté comme contrainte explicite avec guidance "static classes only".

### Conflits bibliothèques tierces

Les utilitaires comme **CVA**, **clsx**, **twMerge** pourraient causer des problèmes. Atténuation par support explicite de `cn()`, `clsx()`, `cva()`, `twMerge()`, `tv()`.

Protection IP CSS

### Noms opaques

Réduction du bundle

### -75% sur exemple

Couverture frameworks

### 10 frameworks

Zero runtime

### Build-time only

Tailwind CSS v4, sorti fin 2024, a introduit une rupture majeure : le moteur a été réécrit en Rust (**Oxide**) et `tailwind.config.js` laisse la place à une configuration **CSS-first** directement dans les feuilles de style. Cette réécriture a effacé du jour au lendemain le seul outil d'obfuscation disponible sur le marché, et ouvert une fenêtre d'opportunité nette : devenir le premier projet compatible v4.

La valeur de l'outil est directement proportionnelle au nombre de frameworks supportés - chaque framework non supporté est un utilisateur perdu. L'obfuscation ne doit jamais casser le rendu : toute classe non détectée produit un **bug visuel silencieux**, le pire type de défaillance en outillage CSS.

## Phases de réalisation

_De la recherche écosystème à la publication npm en 6 semaines_

### Recherche & Analyse (7 déc 2025)

- J'ai analysé l'écosystème en détail : étude approfondie des limitations de tailwindcss-mangle et de <a href="https://www.npmjs.com/package/tailwindcss-patch" target="_blank" rel="noopener noreferrer" class="text-primary underline">tailwindcss-patch</a>
- En parallèle, j'ai fait le reverse engineering des dépôts concurrents (<a href="https://github.com/sonofmagic/tailwindcss-mangle" target="_blank" rel="noopener noreferrer" class="text-primary underline">sonofmagic/tailwindcss-mangle</a>, <a href="https://github.com/tailwindlabs/tailwindcss" target="_blank" rel="noopener noreferrer" class="text-primary underline">tailwindlabs/tailwindcss</a>)
- Côté Tailwind v4, j'ai catalogué les changements (2 500+ lignes d'analyse) et leur impact sur l'obfuscation
- Sur la base de ces observations, j'ai bâti une roadmap d'implémentation en 3 phases priorisées par criticité

### Moteur central (7-15 déc 2025)

- J'ai livré 5 extracteurs spécialisés (~1 400 lignes) : HTML, JSX/TSX, Vue SFC, Svelte, CSS, avec détection de 100+ variants Tailwind
- Côté transformation, j'ai conçu 6 transformers (~1 500 lignes) en double mode - regex (rapide) et <a href="https://lihautan.com/babel-ast-explorer/" target="_blank" rel="noopener noreferrer" class="text-primary underline">Babel AST</a> (Abstract Syntax Tree) via Babel/PostCSS (précis)
- J'ai implémenté le moteur central (~2 400 lignes) : contexte partagé, cache persistant, génération de noms déterministe et aléatoire cryptographique
- Pour fiabiliser le debugging, j'ai ajouté le support des source maps via magic-string

### Plugins & Intégrations (8-15 déc 2025)

- **Plugin Vite** : j'ai branché les hooks configResolved, buildStart, transform, transformIndexHtml, generateBundle et closeBundle
- **Plugin Webpack** : j'ai greffé les hooks beforeCompile, compilation, processAssets et afterEmit
- **Plugin Rollup** : j'ai câblé les hooks buildStart, transform, generateBundle et closeBundle
- **Plugin esbuild** : j'ai raccordé les hooks onStart, onLoad et onEnd
- **Module Nuxt** : j'ai conçu l'auto-détection Vite/Webpack, le chargement de config et l'intégration au lifecycle Nuxt

### Tests & Documentation (8-18 déc 2025)

- J'ai construit **21 applications de test** couvrant **10 frameworks** et **2 versions de Tailwind**
- Côté couverture, j'ai écrit **295 cas de test** dans **92 blocs describe** couvrant tous les extracteurs, transformers et cas limites
- Pour l'adoption, j'ai produit un site de documentation VitePress complet (**34 fichiers Markdown**, **10 400 lignes**)
- Sur le volet design, j'ai créé les assets de marque : logos SVG custom (clair/sombre), icônes et 840 lignes de CSS custom

### Publication (15 déc 2025)

- Le 15 décembre 2025, j'ai publié le package sur le registre npm en tant que **tailwindcss-obfuscator v1.0.0**
- Pour l'interopérabilité, j'ai configuré les exports du package pour **ESM + CJS + DTS** via tsup
- Enfin, j'ai rédigé un README professionnel avec badges, quick start et matrice de compatibilité

## Acteurs & Interactions

_Comment j'ai collaboré avec l'IA pour produire 82K lignes de code_

### Pourquoi le rôle humain était critique

### José DA COSTA - Conception & Direction (~25%)

- **Vision produit** : j'ai identifié le manque sur le marché pour un obfuscateur compatible v4
- **Décisions d'architecture** : j'ai choisi le monorepo TurboRepo, pnpm workspaces et l'approche par analyse statique
- **Pivots stratégiques** : en cours de route, j'ai abandonné <a href="https://www.npmjs.com/package/tailwindcss-patch" target="_blank" rel="noopener noreferrer" class="text-primary underline">tailwindcss-patch</a> au profit d'un package custom
- **Prompt engineering** : j'ai rédigé les instructions détaillées transmises à l'IA, découpé les tâches en étapes vérifiables et cadré le périmètre à chaque itération
- **Directives de style** : j'ai fixé les conventions de code (TypeScript strict, nommage, organisation des modules), la charte éditoriale de la documentation, ainsi que les choix de couleurs et logos
- **Revue de code** : j'ai relu systématiquement chaque module produit par l'IA, validé les choix d'implémentation et refactorisé manuellement quand nécessaire
- **Vérification de conformité** : j'ai contrôlé la cohérence entre code, tests et documentation, et validé l'alignement avec les spécifications Tailwind v3/v4
- **Systèmes de contrôle qualité** : j'ai mis en place la configuration Vitest, ESLint, TypeScript strict, les règles d'interdiction TODO/FIXME et les seuils de couverture de tests
- **Contrôle qualité visuel** : j'ai vérifié visuellement chaque page de documentation, mené les tests manuels bout en bout sur les 21 apps de test et formulé des demandes de corrections ciblées
- **Gestion du périmètre** : j'ai ajouté les frameworks de façon progressive (SvelteKit, Astro, Qwik, Solid.js, Remix) et arbitré les compromis scope/qualité/délai
- **Validation des livrables** : j'ai mené les tests d'intégration manuels, vérifié les exports ESM/CJS/DTS et validé le README et la matrice de compatibilité avant publication npm

### Claude Code (IA) - Implémentation technique (~75%)

- **Code source** : écriture de l'intégralité des 25 modules TypeScript (7 401 lignes) - extracteurs, transformers, plugins, CLI, API publique
- **Tests unitaires** : création de l'ensemble des 295 cas de test Vitest (4 013 lignes), couverture exhaustive des extracteurs, transformers et cas limites
- **Documentation** : rédaction des 34 fichiers Markdown (10 404 lignes) - guides, référence API, matrices de compatibilité, exemples par framework
- **Applications de test** : construction et configuration de 21 apps réelles sur 10 frameworks (React, Vue, Nuxt, SvelteKit, Astro, Qwik, Remix, Solid.js, Next.js, HTML)
- **Design** : création des logos SVG clair/sombre, personnalisation du thème VitePress (840 lignes CSS custom), icônes et assets de marque
- **Recherche & analyse** : étude de la documentation Tailwind v3/v4, reverse engineering des concurrents, catalogue des 100+ variants à supporter (3 000 lignes)
- **Outillage de build** : configuration tsup pour exports ESM + CJS + DTS, setup TurboRepo et pnpm workspaces, scripts de publication npm
- **Itérations correctives** : application des retours de revue, correction des faux négatifs d'extraction, ajustements fins des patterns regex et AST

### Dépendances externes

- J'ai mené ce projet en **binôme Humain + IA**. J'ai tenu les rôles de Product Owner, Tech Lead et QA, tandis que Claude Code (assistant IA Anthropic) prenait en charge toute l'implémentation du code, des tests et de la documentation.
- La collaboration a suivi un schéma clair : je formulais mes besoins en langage naturel, Claude Code exécutait avec des choix d'implémentation techniques, et je vérifiais visuellement avant de demander des ajustements.

J'ai utilisé l'IA pour accélérer la production de code, mais la direction du projet est restée entièrement humaine : c'est de là que venaient le cap produit, l'architecture et les critères d'acceptation. Sans ce pilotage en amont, l'agent aurait produit du code techniquement correct mais résolvant le mauvais problème. La liste ci-dessous détaille concrètement ce que ce rôle recouvre au quotidien.

Les ~100 prompts ont produit ~82 000 lignes de code et documentation, soit en moyenne **~820 lignes par prompt**. Ce ratio illustre l'effet de levier de l'IA sur la productivité.

Registre npm (publication), <a href="https://github.com/josedacosta/tailwindcss-obfuscator" target="_blank" rel="noopener noreferrer" class="text-primary underline">GitHub</a> (hébergement du code), <a href="https://josedacosta.github.io/tailwindcss-obfuscator/" target="_blank" rel="noopener noreferrer" class="text-primary underline">site de documentation</a>, Tailwind CSS v3 & v4 (framework cible), Babel (parsing AST - Abstract Syntax Tree - JSX/TSX), PostCSS (parsing AST CSS).

## Résultats & Métriques

_Premier outil d'obfuscation Tailwind v4 sur le marché_

### Métriques techniques

### Code source TypeScript du package

### Dans 92 blocs describe

### Lignes de documentation (ratio 140% vs code)

### Frameworks frontend supportés

### Vite, Webpack, Rollup, esbuild

### Applications de test réelles

### Pour moi

### Pour la communauté

Lignes source

### 7 401

Cas de test

### 295

Documentation

### 10 404

Frameworks

### 10

Bundlers

### 4

Apps de test

### 21

Sur le plan technique, ce projet a approfondi mon expertise en **manipulation d'AST (Abstract Syntax Tree)** (Babel parser/traverse, PostCSS selector parsing), en **architecture de plugins** pour 4 bundlers et dans le **pipeline de publication npm**. Travailler avec les internals Tailwind v4 Oxide m'a apporté une compréhension précieuse de l'outillage JavaScript basé sur Rust. Mais surtout, ce projet a changé ma façon de travailler : j'ai validé un pattern de collaboration Humain + IA que j'applique désormais à tous mes projets - cadrage humain fort en amont, exécution déléguée à l'agent, puis vérification systématique des livrables.

Premier et seul outil d'obfuscation Tailwind compatible v4 disponible sur npm. Publié en open source, impact mesurable via les compteurs de téléchargement npm. Comble le vide laissé par le concurrent bloqué sur v3, offrant à la communauté une solution prête pour la production en matière de protection de propriété intellectuelle CSS.

## Les lendemains du projet

_De la publication à la maintenance continue_

### Immédiat (déc 2025)

### Moyen terme

### État actuel

Publication de la **v1.0.0 sur npm** avec **README professionnel**, **matrice de compatibilité** et **site de documentation VitePress**. Le package était immédiatement utilisable via `npm install tailwindcss-obfuscator` avec des **paramètres par défaut sans configuration**.

Le projet est en **mode maintenance**, **surveillant les mises à jour de Tailwind CSS** pour d'**éventuelles ruptures de compatibilité**. L'**architecture modulaire** (extracteurs, transformers et plugins séparés) facilite l'**ajout de support** pour de nouveaux frameworks ou bundlers.

Publié sur npm (v1.0.0), source sur <a href="https://github.com/josedacosta/tailwindcss-obfuscator" target="_blank" rel="noopener noreferrer" class="text-primary underline">GitHub</a>, <a href="https://josedacosta.github.io/tailwindcss-obfuscator/" target="_blank" rel="noopener noreferrer" class="text-primary underline">documentation en ligne</a>. L'approche par analyse statique s'est avérée plus résiliente que l'approche par patch du concurrent, validant la décision architecturale initiale.

## Regard critique

_Comment je juge ce projet avec le recul_

### Les enseignements durables que ce projet m'a apportés

- **J'ai mesuré que l'IA sans vérification ne sert à rien** : les agents de code sont des **systèmes probabilistes** dont la sortie varie d'une exécution à l'autre. Sans **vérification systématique** (tests automatisés, linting, revue manuelle), aucun contrôle qualité n'est possible. Générer du code est la partie facile. La vraie difficulté, c'est de savoir **quoi construire**, **comment le vérifier** et **où poser les bons garde-fous**. Cela demande une expérience d'ingénierie concrète, des heures de recherche et des centaines de décisions techniques raisonnées avant même de lancer un agent. *"L'IA décuple la valeur de l'expérience, pas celle de l'ignorance. Les seniors exploitent l'IA, les juniors l'utilisent."*
- **Je privilégie désormais les applications de test réelles** : plutôt que de tester en isolation, construire des apps qui exercent l'outil en conditions de production est le meilleur moyen de valider la compatibilité.
- **Le double mode de parsing** est un pattern que je réutiliserai : proposer deux niveaux de précision avec des compromis explicites fonctionne pour tout outil de transformation de code.
- **Je traite la documentation comme un investissement**, pas comme une corvée de fin : je l'ai produite en parallèle du code plutôt qu'après, ce qui a facilité l'adoption et réduit le coût de support - j'applique désormais ce principe à tout projet open source.

- Avec le recul, je mesure la justesse de l'**approche par analyse statique** que j'ai choisie : elle rend l'outil indépendant des internals Tailwind
- Je couvre **10 frameworks x 2 versions Tailwind** avec **21 apps de test**, ce qui me donne un solide filet de non-régression
- Le double parsing (regex rapide + AST précis via Babel et PostCSS) que j'ai implémenté offre deux niveaux de précision explicites à l'utilisateur
- J'ai tenu la ligne : zéro TODO/FIXME, TypeScript strict, architecture propre
- Le ratio **140 % documentation/code** (10 400 lignes de documentation) reflète mon investissement assumé dans l'adoption

- Je n'ai pas encore mis en place de pipeline CI/CD (GitHub Actions) pour les tests automatisés
- Je me suis limité aux tests unitaires, sans tests E2E pour l'instant
- Côté git, je n'ai pas posé de tags/releases pour le suivi de versions
- Je n'ai déposé que 3 commits de bootstrap, sans historique git granulaire
- Les 8 apps de recherche "lab-*" que j'ai conservées pourraient désormais être archivées

### Contexte additionnel

- Distribution du code (K lignes)
- Architecture des modules du package
- Support frameworks (apps de test)
- Impact de l'obfuscation
- Chronologie du développement
- Répartition des contributions
- Distribution des technologies
- Indicateurs de qualité
- Couverture des variants Tailwind (100+)
- Matrice d'évaluation des risques

## Compétences mobilisées

_Compétences techniques et humaines appliquées_

- **[Résolution de Problèmes & Adaptabilité](https://portfolio.josedacosta.info/fr/competences/resolution-de-problemes-adaptabilite.md)** - Montée en compétence rapide et autonome sur 3 domaines inédits (Babel AST, PostCSS, internals Rust/Oxide) pour livrer le package en 6 semaines - Choix de l'analyse statique : résolution du défi v4 qui bloquait le concurrent
- **[Architecture Logicielle & Système](https://portfolio.josedacosta.info/fr/competences/architecture-logicielle-systeme.md)** - Pipeline modulaire (extracteurs, transformeurs, plugins) pour 10 frameworks
- **[Développement Fullstack](https://portfolio.josedacosta.info/fr/competences/developpement-fullstack.md)** - Package npm avec 25 modules TS, 5 plugins de bundlers, Babel AST et PostCSS
- **[DevOps, Cloud & Industrialisation Production](https://portfolio.josedacosta.info/fr/competences/devops-cloud-industrialisation-production.md)** - Monorepo TurboRepo + pnpm, exports ESM/CJS/DTS via tsup, publication npm automatisée
- **[Innovation & Veille Technologique](https://portfolio.josedacosta.info/fr/competences/innovation-veille-technologique.md)** - Open-source npm package shipped publicly: technology watch on Tailwind v4, Babel AST, Rust/Oxide internals, and PostCSS to outpace a paid competitor

## Parcours associé

_Expérience professionnelle liée à cette réalisation_

- **ACCENSEO - CTO & Fondateur** - Société de conseil et développement informatique offrant des services complets : développement logiciel sur mesure, intégration de systèmes, infrastructure cloud, hébergement de bases de données et conseil technique. Accompagnement des PME et ETI dans la transformation de leur SI en avantage concurrentiel.

## Galerie d'images

_Captures et visuels du projet_

## Vous avez un package npm open-source à concevoir ?

J'ai publié tailwindcss-obfuscator sur npm : plugin PostCSS/Tailwind avec obfuscation déterministe, source maps et intégration CI/CD. Parlons de votre contexte.

**Contactez-moi**
