Fixed: Can't Resolve 'tailwindcss' in Laravel + Vite (v4)

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

▲ browser console / vite overlay
[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:

  1. You have the @tailwindcss/vite plugin installed and registered in vite.config.js, but npm install silently resolved the tailwindcss package 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.
  2. A leftover postcss.config.js from 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.
  3. A stale tailwind.config.js and old @tailwind directives 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

  1. Run npm ls tailwindcss and confirm it reports a 4.x version, not 3.x.
  2. If it's on v3, uninstall tailwindcss, @tailwindcss/vite, postcss, and autoprefixer, then reinstall tailwindcss@latest and @tailwindcss/vite@latest.
  3. Delete postcss.config.js and tailwind.config.js if either still exists in your project root.
  4. Open vite.config.js and confirm tailwindcss() from @tailwindcss/vite is listed as a plugin alongside the laravel() plugin.
  5. Open your main CSS entry file and replace any leftover @tailwind base/components/utilities; lines with a single @import "tailwindcss";.
  6. Stop and restart npm run dev completely (a code change alone won't clear Vite's dependency pre-bundling cache) and confirm the error is gone.
⚠ Edge case: if you're using a starter kit or admin package (Breeze, Jetstream, Filament, or a third-party UI kit) that was built against Tailwind v3, it may ship its own 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.

Advertisement
Advertisement