Editorial
18 April 2026 anonym93 Studio laravel vite tailwindcss

How to Configure Laravel 12 + Vite + Tailwind v4 for a Production-Ready Project

Complete guide to bootstrap a Laravel 12 project with Vite 7 and Tailwind CSS v4 — from installation and `.env` setup, to queue workers, caching, and deployment. Real-world examples from production.

How to Configure Laravel 12 + Vite + Tailwind v4 for a Production-Ready Project

Why Laravel 12 + Vite + Tailwind v4 in 2026

This stack has become the default for modern PHP web applications. Laravel 12 ships with a simplified file structure, Vite 7 delivers blazing-fast builds, and Tailwind CSS v4 uses a new CSS-native engine with no PostCSS config required.

In this guide I'll walk you through exactly what I used for anonym93.dev — a Laravel 12 + Blade + Alpine.js + Filament Admin project, with Vite bundling CSS only.

1. Installing Laravel 12

composer create-project laravel/laravel my-project

cd my-project

php artisan --version

# Laravel Framework 12.x.x

For anyone migrating from Laravel 11: the new structure no longer has app/Console/Kernel.php or app/Http/Kernel.php. Middleware is now registered in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {

$middleware->append(\App\Http\Middleware\SecurityHeaders::class);

})

2. Configuring .env for Production

Copy .env.example to .env:

APP_NAME="My Project"

APP_ENV=production

APP_DEBUG=false

APP_URL=https://example.com

DB_CONNECTION=mysql

DB_HOST=127.0.0.1

DB_PORT=3306

DB_DATABASE=my_project

DB_USERNAME=my_user

DB_PASSWORD=secret

CACHE_STORE=redis

SESSION_DRIVER=redis

QUEUE_CONNECTION=redis

REDIS_HOST=127.0.0.1

REDIS_PASSWORD=null

REDIS_PORT=6379

Generate the key:

php artisan key:generate

Tip: never commit .env to git. Make sure it's in .gitignore (default in Laravel).

3. Installing Vite 7 + Tailwind CSS v4

npm install vite@^7 laravel-vite-plugin@^2

npm install @tailwindcss/vite@^4 tailwindcss@^4 @tailwindcss/typography

vite.config.js

Tailwind v4 uses the official Vite plugin — you no longer need postcss.config.js:

import { defineConfig } from "vite";

import laravel from "laravel-vite-plugin";

import tailwindcss from "@tailwindcss/vite";

export default defineConfig({

plugins: [

tailwindcss(),

laravel({

input: ["resources/css/app.css"],

refresh: true,

}),

],

});

resources/css/app.css

@import "tailwindcss";

@source "../views";

@theme {

--color-primary: hsl(265, 90%, 60%);

--color-background: hsl(240, 15%, 5%);

--font-display: "Inter", system-ui, sans-serif;

}

@layer base {

body {

background-color: hsl(var(--color-background));

color: hsl(var(--color-foreground));

}

}

Important in v4: you no longer need tailwind.config.js if you don't have plugins. Configuration lives directly in CSS via @theme.

4. Integration in Blade

In resources/views/layouts/app.blade.php:

<!DOCTYPE html>

<html lang="{{ app()->getLocale() }}">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{{ $title ?? config('app.name') }}</title>

@vite('resources/css/app.css')

</head>

<body>

{{ $slot }}

</body>

</html>

5. Queue Worker + Supervisor

For async jobs (emails, webhooks, scheduled tasks):

php artisan queue:work --tries=3 --max-time=3600

In production, run it via Supervisor. Create /etc/supervisor/conf.d/my-project.conf:

[program:my-project-worker]

process_name=%(program_name)s_%(process_num)02d

command=php /var/www/my-project/artisan queue:work --sleep=3 --tries=3 --max-time=3600

autostart=true

autorestart=true

user=www-data

numprocs=2

redirect_stderr=true

stdout_logfile=/var/log/my-project-worker.log

Then:

sudo supervisorctl reread

sudo supervisorctl update

sudo supervisorctl start my-project-worker:*

6. Cache and Optimization

For production, cache config, routes and views:

php artisan config:cache

php artisan route:cache

php artisan view:cache

php artisan event:cache

Warning: after every deploy you must re-run these commands, or clear them if you change configs.

7. Production Build

npm run build

Output goes to public/build/. Vite generates a manifest.json with hashed filenames for automatic cache busting.

8. Composer Dev Script

Laravel 12 ships with a dev script that runs everything in parallel. Edit composer.json:

"scripts": {

"dev": [

"Composer\\Config::disableProcessTimeout",

"npx concurrently -c \"#93c5fd,#c4b5fd,#fb7185,#fdba74\" \"php artisan serve\" \"php artisan queue:listen\" \"php artisan pail\" \"npm run dev\" --names=server,queue,logs,vite"

]

}

Then simply:

composer dev

Runs the server, queue worker, log tail and Vite — all in parallel.

9. Deployment Checklist

Before git push to production:

  • APP_ENV=production and APP_DEBUG=false
  • npm run build executed
  • composer install --no-dev --optimize-autoloader
  • php artisan migrate --force
  • php artisan config:cache && php artisan route:cache && php artisan view:cache
  • Correct permissions: storage/ and bootstrap/cache/ writable by web user
  • HTTPS configured (Let's Encrypt / Certbot)
  • Queue worker started via Supervisor

Conclusion

The Laravel 12 + Vite 7 + Tailwind v4 stack is enough for 95% of modern web projects. It's fast, stable, has a rich ecosystem, and is easy to maintain.

For full VPS deployment, see Laravel VPS Deployment Without Docker.

For migrating from an SPA (React, Vue) to Blade, read How to Migrate from React SPA to Blade + Alpine.js.

Cookie preferences

The controls below manage only local analytics consent (GA4). Google Ads / AdSense consent must be handled separately through Google Privacy & Messaging or another certified CMP. See details in Privacy Policy.