angulartailwind-csstailwind-css-4

TailwindCSS V4 in Angular 19 - Changes in CSS Not Reflecting Without Restarting ng serve


I'm working on an Angular 19 project with Tailwind CSS 4. When I make a typo in a class inside my styles.css, Angular throws an error in the console, which is expected. However, even after fixing the typo, the error persists unless I stop and restart ng serve.

Project Structure:

\---src
    |   index.html
    |   main.ts
    |   styles.css
    |
    +---app
    |   |   app.component.css
    |   |   app.component.html
    |   |   app.component.spec.ts
    |   |   app.component.ts
    |   |   app.config.ts
    |   |   app.routes.ts
    |   |
    |   +---landing
    |   \---shared
    \---environments
            environments.ts

Initial app.component.css that caused the issue:

@import "tailwindcss";

#title {
  @apply bg-[url("/backgrounds/bg2.png")] bg-contain bg-center border-spacing-y-8  sm:bg-contain bg-no-repeat sm:h-screen h-96 bborder-2;
}

* {
  @apply p-0 m-0;
}

I mistakenly wrote bborder-2 instead of border-2. This caused the following error:

[ERROR] Cannot apply unknown utility class: bborder-2 [plugin angular-css]

After fixing the typo (bborder-2border-2), the error persists:

@import "tailwindcss";

#title {
  @apply bg-[url("/backgrounds/bg2.png")] bg-contain bg-center border-spacing-y-8  sm:bg-contain bg-no-repeat sm:h-screen h-96 border-2;
}

* {
  @apply p-0 m-0;
}

Console:

X [ERROR] Cannot apply unknown utility class: bborder-2 [plugin angular-css]

    node_modules/tailwindcss/dist/lib.js:17:346:
      17 │ ...r,{onInvalidCandidate:V=>{throw new Error(`Cannot apply unknown...
         ╵                                    ^

    at onInvalidCandidate (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:17:347)
    at ne (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:12:115698)
    at $e (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:17:310)
    at Lr (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:33:724)
    at async Mr (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:33:977)
    at async ot (E:\Angular\mi-portafolioV2\node_modules\@tailwindcss\node\dist\index.js:10:3272)
    at async p (E:\Angular\mi-portafolioV2\node_modules\@tailwindcss\postcss\dist\index.js:8:3242)
    at async Object.Once (E:\Angular\mi-portafolioV2\node_modules\@tailwindcss\postcss\dist\index.js:8:3443)
    at async LazyResult.runAsync (E:\Angular\mi-portafolioV2\node_modules\postcss\lib\lazy-result.js:293:11)
    at async compileString (E:\Angular\mi-portafolioV2\node_modules\@angular\build\src\tools\esbuild\stylesheets\stylesheet-plugin-factory.js:244:31)

  This error came from the "onLoad" callback registered here:

    node_modules/@angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js:125:22:
      125 │                 build.onLoad({ filter: language.fileFilter, names...
          ╵                       ~~~~~~

    at setup (E:\Angular\mi-portafolioV2\node_modules\@angular\build\src\tools\esbuild\stylesheets\stylesheet-plugin-factory.js:125:23)    
    at handlePlugins (E:\Angular\mi-portafolioV2\node_modules\esbuild\lib\main.js:1151:21)


Watch mode enabled. Watching for file changes...
Application bundle generation failed. [0.109 seconds]

X [ERROR] Cannot apply unknown utility class: bborder-2 [plugin angular-css]

    node_modules/tailwindcss/dist/lib.js:17:346:
      17 │ ...r,{onInvalidCandidate:V=>{throw new Error(`Cannot apply unknown...
         ╵                                    ^

    at onInvalidCandidate (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:17:347)
    at ne (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:12:115698)
    at $e (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:17:310)
    at Lr (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:33:724)
    at async Mr (E:\Angular\mi-portafolioV2\node_modules\tailwindcss\dist\lib.js:33:977)
    at async ot (E:\Angular\mi-portafolioV2\node_modules\@tailwindcss\node\dist\index.js:10:3272)
    at async p (E:\Angular\mi-portafolioV2\node_modules\@tailwindcss\postcss\dist\index.js:8:3242)
    at async Object.Once (E:\Angular\mi-portafolioV2\node_modules\@tailwindcss\postcss\dist\index.js:8:3443)
    at async LazyResult.runAsync (E:\Angular\mi-portafolioV2\node_modules\postcss\lib\lazy-result.js:293:11)
    at async compileString (E:\Angular\mi-portafolioV2\node_modules\@angular\build\src\tools\esbuild\stylesheets\stylesheet-plugin-factory.js:244:31)

  This error came from the "onLoad" callback registered here:

    node_modules/@angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js:125:22:
      125 │                 build.onLoad({ filter: language.fileFilter, names...
          ╵                       ~~~~~~

    at setup (E:\Angular\mi-portafolioV2\node_modules\@angular\build\src\tools\esbuild\stylesheets\stylesheet-plugin-factory.js:125:23)    
    at handlePlugins (E:\Angular\mi-portafolioV2\node_modules\esbuild\lib\main.js:1151:21)

Even though the class is now correct, Tailwind does not seem to recognize the fix unless I restart my Angular server (npm run start).

Package Versions (package.json)

"dependencies": {
  "@angular/common": "^20.0.0-next.1",
  "@angular/core": "^20.0.0-next.1",
  "tailwindcss": "^4.0.12",
  "@tailwindcss/postcss": "^4.0.12",
  "postcss": "^8.5.3"
}

Solution

  • After a quick search, it turns out that this bug was recently reported to Angular. It was just fixed a few hours ago, and you'll likely get the fix in the next Angular release:

    Currently latest Angular release: v19.2.1 - 2025-03-05 (5 days ago)

    The issue is likely to be resolved starting from version v19.2.2. So, to properly use TailwindCSS v4, you will need at least version v19.2.2.

    Update

    Issue closed as not planned in Angular.

    It still doesn't work properly in a more complex real life Angular application with nested (mutually imported) CSS files.

    Closing as there isn’t much we can do here. Tailwind is throwing an exception that causes the underlying PostCSS instance to crash and not return which files to watch.