Fix "Missing specifier" & npx tailwindcss init Errors
Why a clean npm install turns a working Vite + Tailwind build into three errors at once, reproduced one at a time with the fix for each.
TL;DR#
Deleting node_modules and running npm install again pulled Tailwind CSS v4 instead of the v3 the project was built on, because package.json had no version pin. v4 moved the PostCSS plugin out of the tailwindcss package and tightened its package.json exports map, so a v3-era postcss.config.js, a v1–v3 three-import stylesheet, or npx tailwindcss init now fail with three different errors from the same root cause. Drop PostCSS entirely and use the official @tailwindcss/vite plugin, or pin tailwindcss@3 if the project is not ready to migrate.
10:04:32 PM [vite] Internal server error: [postcss] It looks like you're trying to use tailwindcss directly as a PostCSS plugin. The PostCSS plugin has moved to a separate package, so to continue using Tailwind CSS with PostCSS you'll need to install @tailwindcss/postcss and update your PostCSS configuration.
Plugin: vite:css
File: ...
10:04:32 PM [vite] Internal server error: [postcss] Missing "./components" specifier in "tailwindcss" package
Plugin: vite:css
File: ...npm error could not determine executable to run
npm error A complete log of this run can be found in: /home/user/.npm/_logs/2025-01-23T15_39_50_870Z-debug-0.logThis is the exact sequence reported on Stack Overflow: "Cannot build frontend using Vite, TailwindCSS with PostCSS" (27 votes, accepted answer): the reporter removed node_modules, reinstalled, and all three errors appeared together — because all three come from one version jump, not three separate bugs.
Why it happens#
All three symptoms come from the same event — npm install resolving Tailwind CSS v4 where v3 used to sit — but each one is a distinct, separately documented break. Confirmed directly against the npm registry and reproduced in a throwaway Vite + React project (Node 22, npm 10):
1. The PostCSS plugin moved to its own package. v3's tailwindcss package doubled as a PostCSS plugin; v4's does not — that specific error, and the full fix for a project that only hits this one, is already covered end to end on Fix: Tailwind PostCSS Plugin Has Moved (Vite + React). This article picks up from there, because the question behind it shows two more errors in the same run that page does not cover.
2. v4 added a strict exports map, and it rejects the old per-layer imports. Older Tailwind setups (v1 through v3) wrote three separate imports in the stylesheet:
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";That worked because v3's package.json has no exports field — Node's legacy resolver let any file under the package resolve, including tailwindcss/components. Checking the npm registry confirms it: tailwindcss@3.4.19's package.json has no exports key. tailwindcss@4.3.3's package.json does, and it only lists ., ./preflight, ./utilities, ./theme, ./colors, ./plugin and a handful of others — ./components and ./base are absent. Importing a path the exports map does not list throws ERR_PACKAGE_PATH_NOT_EXPORTED, reproduced directly with Node's own ESM loader against the installed package (no Vite involved):
node:internal/modules/esm/resolve:318
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './components' is not defined by "exports" in node_modules/tailwindcss/package.json imported from t.mjs
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'Rebuilding the same CSS through Vite's own PostCSS/postcss-import pipeline produces the same resolution failure, worded by that tool's own resolver rather than Node's. The wording a given install shows depends on which resolver reaches the bad path first (Vite's postcss-import, in the question; Node's loader, in this reproduction) — the cause is the same missing subpath either way. Three imports, one old-style @tailwind directive line, or anything else that reaches into tailwindcss/<layer> hits the same wall under v4.
3. The CLI binary moved to its own package too. npx tailwindcss init ran tailwindcss's own command-line tool in v3 — its package.json lists "bin": {"tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js"}, confirmed on the registry. v4's tailwindcss@4.3.3 package.json has no bin field at all: the CLI moved to a separate @tailwindcss/cli package ("bin": {"tailwindcss": "./dist/index.mjs"}, confirmed the same way). npx cannot find an executable named tailwindcss inside a package that no longer ships one, so it fails before ever reaching Tailwind's code:
npm error could not determine executable to runReproducing npx tailwindcss init against a fresh install of tailwindcss@4.3.3 throws the identical npm error, confirming the cause is the missing bin entry rather than anything project-specific.
Fix#
For the first error (PostCSS plugin moved), follow Fix: Tailwind PostCSS Plugin Has Moved (Vite + React) exactly: uninstall postcss/autoprefixer, delete postcss.config.js, install @tailwindcss/vite, register it in vite.config.ts. That one change also clears the second error in this question, because the per-layer @import lines live in the same stylesheet the PostCSS migration touches:
1. Replace the three-layer import with a single one, in the same index.css the old @tailwind directives or @import "tailwindcss/components" lines were in:
@import "tailwindcss";There is no partial fix for the exports error — v4 does not expose ./base, ./components or ./utilities under any configuration, so every file that still imports one of those three paths has to switch to the single import, not just the one Vite first complains about. Reproducing this against the project from the repro above — postcss.config.js and the three-layer import both gone, @tailwindcss/vite and the single @import in — builds cleanly: 20 modules transformed, dist/assets/index-C12XgS7F.css (8.37 kB) written, no PostCSS or resolution error.
2. For the third error (npx tailwindcss init failing), the CLI itself moved, not just its invocation. Running npx tailwindcss init against v4 will keep failing with "could not determine executable to run" no matter how many times node_modules is reinstalled, because the package being asked for an executable genuinely does not ship one any more. Installing the new @tailwindcss/cli package does not bring init back either — running npx @tailwindcss/cli --help against v4.3.3 lists only build and canonicalize; there is no init subcommand in v4 at all, because v4 dropped the generated tailwind.config.js step. A project that needs init is really a project that still wants v3's JS-based config workflow — the fix for that is pinning the version (next step), not chasing the CLI package.
3. If v4 is not an option yet (a design system still keyed to v3's JS-based config and plugins that are not v4-compatible), pin the major version instead of migrating:
npm install -D tailwindcss@3 autoprefixer postcssWith tailwindcss@3 reinstalled, the original postcss.config.js and the three-layer @import lines both resolve again, because v3 is what they were written for, and npx tailwindcss init works again, since v3's own bin entry is back. The underlying bug across all three errors is the same: nothing in package.json pinned a major version, so npm install was free to resolve whatever tailwindcss release was published most recently on the day it ran. Writing an exact version (or at least a range confined to one major, not a bare caret range covering the next major) is what stops the same jump from happening on the next clean install.
Verify the fix#
rm -rf node_modules package-lock.json
npm install
npm run buildA clean reinstall from scratch should produce the same successful build as the fix above — this is the exact sequence ("remove node_modules, reinstall, build") that triggered the original errors, so re-running it is the honest test that the version is now pinned or the migration is complete. Check which major version actually installed with npm ls tailwindcss.
One email a month — the latest explained errors
What the site published that month — mostly Next.js, Supabase and Node errors, explained. You confirm by email; unsubscribe any time in one click.
The next error#
If the build now succeeds but utility classes render unstyled — most often border-border or another shadcn/ui colour token — the cause is a different v4 change: it stopped auto-loading tailwind.config.js. Fix "Cannot apply unknown utility class border-border" covers the @config directive and the @theme block that fix it. If instead an environment variable that worked in npm run dev comes back undefined once this same build succeeds, see Fix: import.meta.env Undefined on Production Build (Vite) — a separate Vite behaviour, not a Tailwind one.
Most "Tailwind suddenly broke" reports share this same shape: nothing in the project changed, but an unpinned tailwindcss dependency resolved a new major version on the next install. Pinning the version is cheaper than re-diagnosing the same three errors on the next clean checkout.
Further reading: Tailwindcss not working with Next.js: fix the config. Also see Tailwind CSS not working after Vite build: dev vs dist. Also see Fix Failed to resolve "@tailwindcss/vite": ESM only error.
Frequently Asked Questions
Still stuck? Paste your error.
Paste the error message or stack trace — we check it against every fix and tool on the site.
Continue Reading
Fix Failed to resolve "@tailwindcss/vite": ESM only error
Why a Vite 6 project that builds fine refuses to load the Tailwind CSS v4 plugin, reproduced step by step, with the two one-line fixes and the variant newer plugin releases print.
Fix: Tailwind PostCSS Plugin Has Moved (Vite + React)
The exact steps to resolve the Tailwind v4 PostCSS plugin relocation error in a Vite + React + TypeScript build.
Fix slow Tailwind v3 in Vite: remove catch-all safelists
Separate oversized generated CSS from plugin cost, with a single-change compiler reproduction and an Autoprefixer negative control.


