A simpler way to add TailwindCSS to your Svelte project

inalbant profile image inalbant ・2 min read

So currently, from what I found, there are only about 3 or 4 articles that show you how to add TailwindCSS to a Svelte app. And I'm pretty sure they all work great, but they're kinda outdated now and include unnecessary things.

On 29th April 2020, Tailwind was updated to v1.4 and added built-in PurgeCSS support. This is great and means that we no longer have to install PurgeCSS ourselves nor set up a config for it.

Okay so, let's get started with the guide!

Step 1: Install dependencies

These 3 dependencies are the only ones we're going to need:

npm i --save-dev tailwindcss postcss-cli npm-run-all

Step 2: Create and configure Tailwind config file

Run the command:

npx tailwind init

Open the newly created tailwind.config.js and add "./src/**/*.svelte" inside the purge options array.
This will ensure that all the thousands of unused CSS rules that Tailwind creates will be purged at build.
Your config should now look like this:

module.exports = {
  purge: ["./src/**/*.svelte"],
  theme: {
    extend: {},
  variants: {},
  plugins: [],

Step 3: Configure PostCSS

Create postcss.config.js in the root folder and add these lines:

const tailwindcss = require("tailwindcss");

module.exports = {
  plugins: [tailwindcss("./tailwind.config.js")],

Step 4: Add Tailwind to your CSS

Create tailwind.css under your public folder, and add these lines:

@tailwind base;
@tailwind components;
@tailwind utilities;

Step 5: Link to CSS in your HTML

Open index.html and link the index.css that will contain the CSS rules that Tailwind will produce for your app. Yes, it doesn't exist yet, but it'll be created by our scripts.

<link rel="stylesheet" href="index.css" />

You can also delete global.css and the link to it in index.html as Tailwind already comes with CSS normalize and resets.

Step 6: Add scripts

In the package.json file, ensure your scripts look like this:

"scripts": {
    "watch:tailwind": "postcss public/tailwind.css -o public/index.css -w",
    "build:tailwind": "NODE_ENV=production postcss public/tailwind.css -o public/index.css",
    "dev": "run-p start:dev autobuild watch:tailwind",
    "build": "npm run build:tailwind && rollup -c",
    "start": "sirv public --single",
    "start:dev": "sirv public --single --dev",
    "autobuild": "rollup -c -w"

That's it! You can start your app with the usual npm run dev command.

Posted on by:


Editor guide

Running npm run dev starts two servers for me. The second stating that port 5000 is already used and it uses a random one.

I think the first is coming from the script start:dev and the second from autobuild. I guess start:dev is not required at all, because autobuild respectively rollup -c -w is already running sirv.


I think you're right. I changed the dev script to "run-p autobuild watch:tailwind" which works just fine


Alright, then I leave it like that and by the way thank you for the post!


The run-p keyword used in the scripts in the package.json will lead port 5000 of localhost could not be used and jump to another random port. I change it to run-s, now it is OK. What is the reason of this?


I had the same problem and changed my dev script to: "dev": "run-p autobuild watch:tailwind" - which seems to work fine for me


Thanks for that post!
2 questions:

  • (1) Why do you (and seemingly everybody else) put tailwind.css into the public folder ? It seems to me that only the generated index.css needs to be there and it makes more sense to put tailwind.css under src/ !?
  • (2) With this setup my @apply rules in the style section seem to get lost or not effective (Before i had it working with the setup of dev.to/sarioglu/using-svelte-with-...). Any way to make this work as well ?

2) This tutorial seems to follow a minimalist mindset and only compiles postcss files, not svelte files. If you want to process postcss in svelte files, follow the other tutorial for everything but purgecss. Everything else that differs is because he is calling postcss directly instead of using svelte-preprocessor which you need for running postcss in svelte files.

1) Source file doesn't have to be there, may need to be moved depending on your tooling. If you follow the other tutorial, both files and the generating npm commands should be deleted and contents put in the <style global> instead.


I'm currently experimenting with Tailwind and still getting my head around the ugly but useful convention of placing lots of modifiers in the markup directly. Quick question: if Svelte automatically scopes our CSS for each component, what would be the advantage of using Tailwind at all? Wouldn't it be cleaner to have the styles inside Svelte's tag instead?</p>


Thanks for this tutorial. I found it really helpful


Great post.
I get the following error on npm run build
'NODE_ENV' is not recognized as an internal or external command,
operable program or batch file.


Ok. This solves it.
npm install --save-optional win-node-env


Excellent tutorial. Should replace the one written by Tailwind author :)


this is brilliant, worked for me!


Do you have a clue how to get this to work with sapper?


For my sapper project I was able to get it running by following steps 1-3 as above then branching off as below:

Step 4: Create static/tailwind.css and add imports
Step 5: Add <link rel='stylesheet' href='index.css' /> to src/template.html
Step 6: Adjust run scripts as follows:

"scripts": {
    "dev": "run-p start:dev watch:tailwind",
    "build": "npm run build:tailwind && sapper build --legacy",
    "watch:tailwind": "postcss static/tailwind.css -o static/index.css -w",
    "build:tailwind": "NODE_ENV=production postcss static/tailwind.css -o static/index.css",
    "export": "sapper export --legacy",
    "start": "node __sapper__/build",
    "start:dev": "sapper dev",
    "cy:run": "cypress run",
    "cy:open": "cypress open",
    "test": "run-p --race dev cy:run"

Then can simply start up with npm run dev


I've created a template for sapper based on this: github.com/jadbox/sapper-tailwind-...

npx degit "jadbox/sapper-template#rollup-tailwind" sapper-tailwind

Hi Jonathan, I see this in my editor when looking at index.svelte
Error in svelte.config.js

Error: ENOENT: no such file or directory, uv_cwdsvelte

any ideas, the app seems to run ok.


There's an error when using @apply


If I run "watch:tailwind" the index.css is generated, but not with "dev"! Any hints on this?


Exactly what I was looking for. Thanks for the post!


Thx for this, helpful!

I tried it but I am getting 66k lines in index.css output, so purge can't be working here?


Thanks for sharing!
Anyone knows why I'm getting this error?