tonysm/tailwindcss-laravel
Tailwind CSS for Laravel: ships a preset, config helpers, and an artisan build command so you can compile Tailwind without Node tooling, plus Blade directives and a facade for cleaner class handling.
tonysm/tailwindcss-laravel wraps the Tailwind CSS standalone CLI so you can build Tailwind without Node, npm, or a package.json. Everything runs through Artisan.
Minimal path:
composer require tonysm/tailwindcss-laravelphp artisan tailwindcss:install — publishes config/tailwindcss.php, downloads the standalone binary for your platform, and scaffolds a CSS entry point.@import "tailwindcss"; in resources/css/app.css.php artisan tailwindcss:build (add --watch while developing).@vite([...]) if you also use Vite, otherwise a plain <link>).Where to look first
config/tailwindcss.php — binary path, version pin, and the input/output CSS locations. This is the file that decides what actually gets compiled and where it lands.@import "tailwindcss", @theme, and @source live in v4.php artisan list | grep tailwind — confirm the exact command set for the installed version before scripting anything around it.First use case: an app with no JS toolchain (or a team that wants one less). Write utility classes in Blade, run the build, ship a single compiled CSS file.
Version note for 2.3.1: this release only bumps the bundled Tailwind CLI to v4.3.3. It's a patch bump — no API or config changes — but the binary it downloads is now newer, so the generated CSS can differ slightly from what you built on 2.3.0.
Dev loop. Run the watcher in a second terminal (or a Composer script) alongside php artisan serve:
"scripts": {
"dev": ["php artisan tailwindcss:build --watch", "@php artisan serve"]
}
The watcher is a real process — if you background it in a single shell, make sure it dies with the parent or you'll accumulate orphaned binaries.
Production build. Build in CI/deploy, not at request time. Sequence: composer install --no-dev → ensure the binary is present (see Gotchas) → php artisan tailwindcss:build → deploy public/ with the compiled CSS. Committing the compiled CSS is a legitimate pattern for this package and makes the binary a build-time-only dependency.
Coexistence with Vite. Pick one owner of the Tailwind pipeline. If you keep @tailwindcss/vite, don't also run tailwindcss:build in dev — you get double compilation and confusing staleness. If you drop the npm dependency, remove the plugin so the two don't fight over the same output file.
Content detection across package boundaries (v4). Auto-detection walks the project, but vendor Blade components, Livewire/Filament views, and anything under vendor/ or a symlinked local package often need explicit @source directives in your CSS entry:
@import "tailwindcss";
@source "../../vendor/acme/ui/resources/views";
This is the single most common "classes work locally, vanish in prod" cause with this package.
Theme customization. With v4, put design tokens in @theme { --color-brand-500: …; } in the CSS entry rather than in a JS config. If you're porting an older project, the old tailwind.config.js is a translation job, not a copy.
Multiple entry points. For separate admin/marketing bundles, run the build per entry with a different input/output pair, either by invoking the command with explicit paths or by wrapping it in a small script; keep each output under public/build so cache-busting stays predictable.
Deploy caching. Cache the downloaded binary keyed on the package version + platform in CI, so every pipeline doesn't re-fetch ~40–100MB.
composer install alone does not guarantee a working build on a fresh machine or container. Your Dockerfile/deploy script must run the install/download step explicitly, and the binary must survive into the build stage.storage/ inside a container that gets rebuilt, your build breaks on first run. Either bake it into the image or point the config at a stable path.tonysm/tailwindcss-laravel to 2.3.1 changes what the install command would download; an already-installed CLI stays on the old version until you re-run the install/download command. Verify with the binary's --help/version output, not composer.lock. This is the most likely reason someone "upgrades to 2.3.1" and sees no change.exec/proc_open disabled. Shared hosting and locked-down PHP images frequently disable these; the Artisan wrapper will fail with an opaque error. This package assumes you can spawn a process.php artisan config:cache is fine, but re-run it after changing binary paths or the cached value will point at the old location.@apply inside scoped styles (Vue/Svelte SFCs, CSS modules) needs an @reference "…/app.css"; line in v4 — otherwise the build fails with unknown-utility errors that look like missing classes.bg-{{ $color }}-500) still don't exist to the compiler — this is unchanged by the wrapper, and is a frequent false alarm when a teammate first hits it.How can I help you explore Laravel packages today?