DEV Community


Posted on

A simpler way to add TailwindCSS to your Svelte project

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: [],
Enter fullscreen mode Exit fullscreen mode

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")],
Enter fullscreen mode Exit fullscreen mode

Step 4: Add Tailwind to your CSS

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

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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

Top comments (23)

tobx profile image
tobx • Edited

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.

mellson profile image
Anders Bech Mellson

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

tobx profile image

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

bluephoen1x profile image

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?

mellson profile image
Anders Bech Mellson

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

o_a_e profile image
Johannes Zillmann

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 Any way to make this work as well ?
linuxhurtme profile image
Today's dumb idea

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.

fatimah profile image

Thanks for this tutorial. I found it really helpful

rafaelbeckel profile image
Rafael Beckel • Edited

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>

grepliz profile image
Liz Lam

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

nongomacoders profile image

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.

nongomacoders profile image

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

heliosnarcissus profile image
Rey Anthony Renacia

this is brilliant, worked for me!

mgudipati profile image
Murty Gudipati

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

brorjoeljonsson profile image
Joel Jonsson

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

alancwoo profile image

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

jadbox profile image
Jonathan Dunlap

I've created a template for sapper based on this:

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

Thread Thread
justageek profile image
Brian Smith

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.

difaananda40 profile image
M Difa Ananda • Edited

There's an error when using @apply

shumy profile image

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

pestrickland profile image
Paul Strickland

Thanks very much, this helped me finally get Svelte and Tailwind working nicely together.

quantuminformation profile image
Nikos • Edited

Thx for this, helpful!

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

mrmono profile image
MrMono • Edited

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