dxgx/blade-tailwind-extract
Laravel package that shrinks Livewire payloads by extracting long Tailwind class strings from Blade/Livewire into short hashed class names and a generated @apply CSS file. Supports class="", @class/->class arrays, dev inject vs prod extract, and collision-safe hashing.
Install the package (dev dependency):
composer require dxgx/blade-tailwind-extract --dev
Publish config (optional):
php artisan vendor:publish --tag=blade-tailwind-extract-config
First use case: Wrap a Blade file
php artisan dg:blade-tailwind:wrap resources/views/components/card.blade.php
This automatically identifies repeated Tailwind class lists and wraps them with semantic names like __card-wrapper__.
Extract to production format:
php artisan dg:blade-tailwind:extract resources/views/components/card.blade.php
This converts wrapped classes to compact TW-* classes and generates CSS @apply rules.
Wrap → Extract → Commit (New files)
php artisan dg:blade-tailwind:wrap resources/views/livewire
php artisan dg:blade-tailwind:extract resources/views/livewire
Restore → Edit → Extract (Existing files)
php artisan dg:blade-tailwind:restore resources/views/components
# Edit Blade files
php artisan dg:blade-tailwind:extract resources/views/components
resources/views/livewire to minimize wire payload.--min=2 for small components (e.g., buttons).:class ternaries independently.# Example GitHub Actions workflow
- name: Extract Tailwind classes
run: |
php artisan dg:blade-tailwind:wrap resources/views --yy
php artisan dg:blade-tailwind:extract resources/views --yy
hash_length: 5 for larger projects to reduce collision risk.reserved_classes to include project-specific patterns.Reserved Classes: Attempting to extract group, peer, or group/ classes will fail with warnings. Use --skip-prefix=TW to avoid accidental extraction of existing TW-* classes.
File Renaming: Moving Blade files after extraction breaks the file-based hash. Solution: Restore → move → extract.
PHP Syntax Errors: The package runs php -l before extraction. Fix syntax errors first.
Ternary Expressions: Both branches of :class ternaries are wrapped independently. Ensure each branch meets the --min threshold.
CSS Sync: Always commit both Blade files and the generated CSS file together.
--dry-run to preview changes without modifying files.storage/logs/laravel.log for skipped patterns and warnings.php artisan dg:blade-tailwind:wrap --min=1 to see all potential candidates.generateWrapperName() in a service provider.TailwindExtractorService to support custom attributes.--yy to skip confirmations in CI/CD.*livewire* to target only Livewire components.@class([...]) are processed independently.# Example: Extract only Livewire components with 4+ classes
php artisan dg:blade-tailwind:wrap resources/views/livewire --min=4 --yy
php artisan dg:blade-tailwind:extract resources/views/livewire --yy
How can I help you explore Laravel packages today?