Skip to main content
ASoc
Tutorial

Tailwind IntelliSense Not Working? It's Looking for a v4 Config

v4 has no tailwind.config.js, so every tool needs pointing at your CSS instead. Six causes, the Prettier pointer this repo sets, and the one that isn't tooling.

The ASoc Team8 min read

Tailwind IntelliSense stops suggesting classes when it cannot find your configuration. In Tailwind v4 that is no longer tailwind.config.js — it is the CSS file containing @import "tailwindcss". Extensions, formatters and language servers that still hunt for a JavaScript config find nothing, and silently degrade to no completions at all.

The short answer

The usual cause in a v4 project is a missing or unfound config entry point. v4 is CSS-first: there is no tailwind.config.js, so every tool that needs to know your theme must be pointed at your CSS file instead. Update the IntelliSense extension to v0.12 or newer, make sure your CSS entry point is inside the workspace, and point your formatter at it explicitly.

Why v4 broke tooling that worked in v3

In v3, tailwind.config.js was the single well-known file every tool looked for. The VS Code extension walked up from the open file until it found one; Prettier's class sorter did the same; the PostCSS plugin read it directly. Delete that file and the whole toolchain lost its anchor.

v4 deletes that file by design. This codebase has no tailwind.config.js at all — the configuration is a @theme block in src/app/globals.css:

@import "tailwindcss";

/* Class-based dark mode (toggled by adding `dark` to <html>) */
@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --font-sans: var(--font-outfit), ui-sans-serif, system-ui, sans-serif;

  --color-primary: #465fff;
  --color-primary-500: #465fff;
  --color-gray-900: #101828;
  --color-title-color: #101828;

  --breakpoint-2xsm: 375px;
  --breakpoint-xsm: 425px;
}

…and a four-line postcss.config.mjs:

const config = {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};

export default config;

That is the entire configuration surface. Nothing in it is named tailwind.config.js, so a tool searching for that filename reports "no Tailwind project here" and goes quiet — which reads, from the editor, exactly like the extension being broken.

The six causes, in the order worth checking

CauseHow you can tellFix
Extension predates v4 supportCompletions work in a v3 repo, not a v4 oneUpdate Tailwind CSS IntelliSense to v0.12+
CSS entry point outside the workspace rootMonorepo, or the app is a subfolder you opened separatelyOpen the folder containing the CSS file, or set tailwindCSS.experimental.configFile
Editing classes in a file type the extension ignoresWorks in .html, not in .mdx/.vue/template stringsAdd the language to tailwindCSS.includeLanguages
Suggestions disabled inside stringsNothing completes inside className="…""editor.quickSuggestions": { "strings": true }
CSS validator flags @theme, @apply, @custom-variantRed squiggles reading "Unknown at rule""css.validate": false, and let the Tailwind server handle the file
Formatter sorts classes wrongly or not at allClass order never changes on savePoint the Prettier plugin at the CSS file (below)

The last one is worth its own paragraph, because it fails quietly rather than visibly.

The formatter needs the same pointer, and this repo sets it

prettier-plugin-tailwindcss sorts class lists in canonical order. To do that it has to resolve your theme — the same resolution problem the editor extension has. In v3 it found tailwind.config.js on its own. In v4 you tell it where the CSS is, via tailwindStylesheet. This project's entire .prettierrc.json:

{
  "plugins": ["prettier-plugin-tailwindcss"],
  "tailwindStylesheet": "./src/app/globals.css"
}

Two lines of config, and without the second one the plugin still runs — it just sorts against stock Tailwind and treats every custom utility in the @theme block as unknown. Classes like bg-primary, text-title-color and max-xsm:hidden get shuffled to the end of the list as if they were arbitrary strings, and npm run format:check starts disagreeing with npm run format for reasons nobody can see in the diff. The failure mode of a missing pointer is not an error; it is a formatter that is confidently wrong.

That is the same shape as the editor symptom. Both tools need the theme; both look for it in a file that v4 does not create; both degrade silently when they cannot find it.

The one that is not a tooling bug at all

There is a failure that looks identical from the editor and has a completely different cause: the class genuinely does not exist yet.

Tailwind v4 with Turbopack does not hot-reload changes to @theme. This is documented in this repo's own CLAUDE.md, in a warning block, because it cost real debugging time:

Tailwind v4 + Turbopack does not hot-reload @theme changes — restart npm run dev after editing color/token vars in globals.css (otherwise new utilities like bg-primary silently fail to generate).

Add --color-brand: #465fff to @theme, save, and type bg-brand in a component. The page does not change colour, and depending on the extension's cache state the completion may not appear either. Nothing is broken: the running dev server has not regenerated the utility, so bg-brand is a class that has not been emitted. Restarting npm run dev fixes both symptoms at once.

The tell is that the existing classes still autocomplete. If bg-primary suggests and bg-brand does not, the extension is fine and the build is stale. If nothing suggests, the extension never found your config.

A working VS Code settings block for a v4 project

This repo does not ship a .vscode/ directory — editor setup is left to the developer. For a v4 project shaped like this one, the settings that matter are:

{
  "editor.quickSuggestions": { "strings": true },
  "css.validate": false,
  "tailwindCSS.includeLanguages": {
    "mdx": "html",
    "typescriptreact": "javascript"
  },
  "tailwindCSS.experimental.configFile": "src/app/globals.css"
}

tailwindCSS.experimental.configFile is the explicit escape hatch: it tells the extension exactly where the entry point is instead of making it search. Set it when the CSS lives somewhere non-obvious, or when one workspace holds several apps and the extension keeps picking the wrong one. css.validate: false turns off the built-in CSS language service that does not know @theme, @custom-variant or @apply — the Tailwind server validates those properly.

The mdx mapping matters here specifically: this site's 269 blog articles are MDX compiled at build time, and without that mapping the extension offers nothing inside a className in an MDX file.

Troubleshooting

SymptomCauseFix
No completions anywhere in the projectExtension never found a config; v4 has no tailwind.config.jsUpdate the extension, then set tailwindCSS.experimental.configFile to your CSS entry point
Completions work in .tsx but not .mdxThe language isn't in the extension's listAdd it to tailwindCSS.includeLanguages
Nothing completes inside className="…"VS Code suppresses suggestions inside strings by default"editor.quickSuggestions": { "strings": true }
"Unknown at rule @theme" squigglesThe built-in CSS validator predates v4 at-rules"css.validate": false
One new custom class won't suggest, others doThe utility hasn't been generated; @theme doesn't hot-reload under TurbopackRestart npm run dev
Prettier reorders classes strangelyThe sorter can't resolve your themeAdd "tailwindStylesheet": "./path/to/globals.css" to .prettierrc.json
Works for a colleague, not for youStale extension cache after a dependency changeReload the window, or run "Tailwind CSS: Restart IntelliSense"
Only broken in a monorepo packageThe extension picked a sibling app's entry pointSet configFile per workspace folder

Frequently asked questions

Does Tailwind IntelliSense work with Tailwind v4? Yes, from extension v0.12 onward. That release taught it to read a CSS entry point instead of requiring tailwind.config.js. An older build in a v4 project finds no config and offers no completions, which is the single most common report behind this search.

Do I need a tailwind.config.js for IntelliSense to work? No. A v4 project configures itself in CSS, and current extension versions handle that. If you want to remove the guesswork, point the extension at the file explicitly with tailwindCSS.experimental.configFile.

Why does Prettier sort my classes differently after upgrading to v4? Because prettier-plugin-tailwindcss lost the config file it used to read and fell back to stock Tailwind, so your custom utilities look unknown to it. Setting tailwindStylesheet in .prettierrc.json restores correct ordering — this project sets it to ./src/app/globals.css.

Why does a class I just added to @theme not autocomplete? Most likely it has not been generated. Tailwind v4 under Turbopack does not hot-reload @theme, so a newly declared token produces no utility until the dev server restarts. Existing classes still completing is the giveaway that this, not the extension, is the problem.

Where to take this next

If the CLI itself is the thing failing rather than the editor, sh: tailwind: command not found covers the install-path side of the same upgrade. For what actually moved into CSS and why, read Tailwind v4 config, and the v4 migration guide for the upgrade itself.

Templates in this post

ASoc Vault, ASoc Vox and ASoc Weave ship with the v4 CSS-first setup described here — @theme tokens, a PostCSS config, and the Prettier pointer already set, so the toolchain resolves on first open.

Browse the full sets: Next.js landing page templates, Tailwind landing page templates.

Keep reading

Tutorial12 min read

Tailwind Max Width: 62 Usages, 57 Arbitrary, and 96 Lost Pixels

max-w-* reads the --container-* scale in v4, and max-w-md is 448px, not 768px. A census of 62 usages here, plus the viewport band where our layout narrows as it widens.

Read more