tailwind-csssvelteturborepotailwind-css-4

Detection of an external (non-package, static) source outside the project


TL;DR: Inside a shared UI library in a Turborepo, styling a component inline with Tailwind CSS classes in @repo/ui does not render the component properly in web, whereas styling the component through styles.css does work.

Background

I'm trying to set up a new monorepo using Turborepo. I want two Svelte applications (e.g., web and docs) and one shared Svelte component library (e.g., @repo/ui). For styling, I want to use Tailwind CSS v4.

I started with the Turborepo with-svelte example and added everything that seemed necessary from the with-tailwind example, adapting it from Next.js to Svelte (to the best of my knowledge). Unfortunately, it does not work properly, and I can't figure out why. I also haven't found any helpful resources for this kind of setup, even though it seems quite practical.

Not working (inline styles)

I have a Button component with inline Tailwind CSS styles in @repo/ui, like this:

# src/Button.svelte
<button
    class="mb-3 rounded-xl bg-[var(--green-1000)] ..."
>
    click
</button>

When I run pnpm dev and open the web app, the button appears without any styling — it just displays the word "click". Also, the packages/ui/dist/styles.css file is identical to packages/ui/src/styles.css.

When I run pnpm --filter=@repo/ui build:styles, the packages/ui/dist/styles.css file contains a lot of generated styles (presumably from the inline Tailwind classes in the Button component). However, these styles are still not applied in the web app when running it with pnpm --filter=web dev. And when I run pnpm dev again, the contents of packages/ui/dist/styles.css disappear.

Working (external styles)

./src/Button.svelte

<button>
    click
</button>

./src/styles.css

@import 'tailwindcss';
@import '@repo/tailwind-config';

button {
  @apply mb-3 rounded-xl bg-[var(--green-1000)] ...;
}

When I use the external styles.css to style the button, it renders perfectly in the web app.

My Assumption

I assume there's a conflict between tailwindcss/vite and tailwindcss/cli in @repo/ui. I tried removing one or the other, but that didn't solve the problem. At this point, I'm stuck.

Has anyone encountered similar issues? Or does anyone know of a working Turborepo setup using Svelte v5 and Tailwind CSS v4 with a shared UI library?

Solution from Tailwind CSS v3

For Tailwind CSS v3, I found several sources suggesting to update the tailwind.config.js and include the UI library as an additional content source:

# tailwind.config.js
export default {
  content: [
    './src/**/*.{html,js,svelte,ts}', 
    '../../packages/ui/**/*.{html,js,svelte,ts}', 
  ],
  ...
}

Unfortunately, this doesn't work in Tailwind CSS v4 because tailwind.config.js no longer exists.

More Code

Here is the package.json from the @repo/ui package, where I tried using only the Tailwind CSS CLI:

{
  "name": "@repo/ui",
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev:components": "svelte-kit sync && svelte-package --watch --input=src",
    "dev:styles": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --watch",
    "build:components": "svelte-kit sync && svelte-package --input=src",
    "build:styles": "tailwindcss -i ./src/styles.css -o ./dist/styles.css",
    "lint": "eslint .",
    "check-types": "svelte-check --tsconfig ./tsconfig.json"
  },
  "files": [
    "dist",
    "!dist/**/*.test.*",
    "!dist/**/*.spec.*",
    "src",
    "!src/**/*.test.*",
    "!src/**/*.spec.*"
  ],
  "sideEffects": [
    "**/*.css"
  ],
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "svelte": "./dist/index.js"
    },
    "./styles.css": "./dist/styles.css"
  },
  "peerDependencies": {
    "svelte": "^5.0.0"
  },
  "devDependencies": {
    "@repo/eslint-config": "workspace:*",
    "@repo/tailwind-config": "workspace:*",
    "@repo/typescript-config": "workspace:*",
    "@sveltejs/kit": "^2.21.1",
    "@sveltejs/package": "^2.0.0",
    "@sveltejs/vite-plugin-svelte": "^5.0.0",
    "@tailwindcss/cli": "^4.1.5",
    "eslint": "^9.27.0",
    "prettier": "^3.5.3",
    "prettier-plugin-tailwindcss": "^0.6.11",
    "svelte": "^5.30.2",
    "svelte-check": "^4.2.1",
    "typescript": "5.8.2",
    "vite": "^6.3.2",
    "tailwindcss": "^4.1.7"
  }
}

Edit: added found solution for Tailwind v3


Solution

  • TailwindCSS v3

    Your v3 solution is correct. You need to declare the paths to external files.

    ./tailwind.config.js

    export default {
      content: [
        './src/**/*.{html,js,svelte,ts}', 
        '../../packages/ui/**/*.{html,js,svelte,ts}', // Specifying access to an external source
      ],
    }
    

    TailwindCSS v4

    In v4, this happens automatically within the project - except for paths declared in .gitignore.

    So in v4, the content array from v3 is generally not existed. However, the folder you want to access is located outside the project. In this case, you can extend v4's automatic source detection by explicitly providing the required path:

    ./src/style.css

    @import "tailwindcss";
    @import "@repo/tailwind-config";
    
    @source "../../../packages/ui"; /* Specifying access to an external source */
    

    Note: It's important to note that the @source directive expects a relative path.