The problem: After following Tailwind's official Laravel + Vite setup guide, npm run dev throws a resolution error the moment you try to load any page, even on a completely fresh install.
Environment: Laravel 11.x/12.x, Tailwind CSS 4.x, @tailwindcss/vite plugin, laravel-vite-plugin, Node 20 LTS.
The Error
[plugin:@tailwindcss/vite:generate:serve] Can't resolve 'tailwindcss' in '/resources/css'
at finishWithoutResolve (node_modules/enhanced-resolve/lib/Resolver.js:564)
at resources/css/app.css
// happens the instant Vite tries to process the
// @import "tailwindcss"; line in your CSS entry file
Why It Happens
Tailwind v4 changed how it's wired into a build tool, and that change is the entire source of this error. In Tailwind v3, your CSS file used @tailwind base; @tailwind components; @tailwind utilities; and a separate PostCSS plugin (tailwindcss) processed those directives using a tailwind.config.js file. In v4, Tailwind ships as a native Vite plugin (@tailwindcss/vite) instead, and your CSS file just has a single @import "tailwindcss"; line.
The resolution error shows up when your project ends up in a half-migrated state — which happens more easily than it sounds, for a few specific reasons:
- You have the
@tailwindcss/viteplugin installed and registered invite.config.js, butnpm installsilently resolved thetailwindcsspackage itself to v3 (common when a lockfile, a starter kit, or a scaffolding command pins an older range), so the plugin and the core package are on mismatched major versions. - A leftover
postcss.config.jsfrom a v3 setup is still trying to process Tailwind through PostCSS at the same time the new Vite plugin tries to process it directly — the two paths conflict, and Vite can't decide which one owns the resolution. - A stale
tailwind.config.jsand old@tailwinddirectives are still present alongside the new@import "tailwindcss";syntax, confusing whichever resolver runs first.
The Fix
1. Confirm which major version actually got installed — this is the single most common root cause:
$ npm ls tailwindcss
If that shows 3.x.x even though you meant to install v4, force the correct versions explicitly:
$ npm uninstall tailwindcss @tailwindcss/vite postcss autoprefixer
$ npm install tailwindcss@latest @tailwindcss/vite@latest
2. Remove every leftover v3 config file — v4 doesn't use a JS config file or PostCSS plugin by default, so these shouldn't exist anymore:
$ rm -f postcss.config.js tailwind.config.js
3. Register the plugin correctly in vite.config.js, alongside laravel-vite-plugin:
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', 'resources/js/app.js'],
refresh: true,
}),
],
});
4. Your CSS entry file should only have one line for Tailwind itself — no old @tailwind directives left alongside it:
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss";
Step-by-Step
- Run
npm ls tailwindcssand confirm it reports a 4.x version, not 3.x. - If it's on v3, uninstall
tailwindcss,@tailwindcss/vite,postcss, andautoprefixer, then reinstalltailwindcss@latestand@tailwindcss/vite@latest. - Delete
postcss.config.jsandtailwind.config.jsif either still exists in your project root. - Open
vite.config.jsand confirmtailwindcss()from@tailwindcss/viteis listed as a plugin alongside thelaravel()plugin. - Open your main CSS entry file and replace any leftover
@tailwind base/components/utilities;lines with a single@import "tailwindcss";. - Stop and restart
npm run devcompletely (a code change alone won't clear Vite's dependency pre-bundling cache) and confirm the error is gone.
tailwind.config.js reference or expect the old @tailwind directive syntax internally. Upgrading your own app to v4 doesn't automatically upgrade a package's bundled views — check that package's own release notes for v4 compatibility before assuming the fix above covers everything.
Still seeing the resolution error after all four steps? Share your vite.config.js and package.json on the Contact page and I'll help track it down.