Tailwind CSS and SvelteKit - The easy way

Adding Tailwind CSS to SvelteKit is a simple 3 step process

Long story short, I needed to integrate Tailwind CSS into a new SvelteKit project and searched around on the Internet on how to do it. The first option is to use svelte-add, but it won't work unless you start off with a fresh project. The other common way to do it is some variation of my old Sapper and Tailwind solution. While it's still valid today turns out there is a much simpler way to do it.

Create new SvelteKit project#

When you create a new SvelteKit project with npm init svelte@next my⁠-⁠app command you have a few options to choose from. The choices you make will affect how easy it will be to integrate Tailwind CSS. For example, here are the choices that I made during my project creation.

SvelteKit Project Setup

As you can see in the screenshot above I chose TypeScript support. In order to get TypeScript working in Svelte you have to use svelte-preprocess library. That library is also the key to get Tailwind working in our project. Its job is to support and process many different languages in Svelte templates and it also has built-in support for PostCSS that Tailwind is based on.

Don't worry if you didn't choose TypeScript as an option in your project. You can install svelte⁠-⁠preprocess separately and implement it in your svelte.config.js like this.

// svelte.config.js

import preprocess from 'svelte-preprocess';

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult
// for more information about preprocessors
preprocess: preprocess(),

kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte'

export default config;

Now that we have PostCSS support in place let's move on and install and configure Tailwind CSS and other required libraries.

Install Tailwind CSS and friends#

First things first, we need to install Tailwind and supporting NPM packages and Tailwind configuration file.

$ npm add -D tailwindcss autoprefixer postcss-load-config
$ npx tailwindcss init

For this to work we also need to create PostCSS configuration in our project directory.

// postcss.config.js

module.exports = {
plugins: {
autoprefixer: {},
tailwindcss: {},

We are almost ready to go, but if you start you project you will get an exception that has the following error message in it somewhere.

Instead rename tailwind.config.js to end in .cjs, change the requiring
code to use import(), or remove "type" : "module" from [...]/package.json

What Node basically says is that it expects a different type of module. The solution is simple. Change extensions for Tailwind and PostCSS configs from .js to .cjs.

In order for Tailwind to know what CSS it needs to purge during production builds you have to add purge patterns to your Tailwind config.

// tailwind.config.cjs

module.exports = {
// add this section
purge: [
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
variants: {
extend: {},
plugins: [],

We now have a correct Tailwind and PostCSS setup in place. Let's use it.

Import your CSS#

The last step is to create a Tailwind CSS file and import it in the project. Create an app.css file under src directory, if it's not there already, and add the following to it.

/* app.css */

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

@layer base {
h1, h2, h3, h4 {
@apply font-bold;

Next step is to require that file in your template. Here I added it to my main layout file.

// __layout.svelte

<script lang="ts">
import '../app.css';

import Header from '$lib/components/Header.svelte';
import Login from '$lib/components/Login.svelte';
{ auth } from '$lib/auth';

<Header name=
{$} />
<div class="max-w-4xl mx-auto py-8">
{#if $auth.loading}
<div class="text-gray-600">Loading ...</div>
{:else if $auth.user}
<slot />
<Login />

If you start the application now the Tailwind CSS should kick in.

<style lang="postcss">
.content {
@apply text-lg text-gray-600;

You can also use Tailwind directives in your style tags. I usually add lang="postcss" to get rid of editor warnings, but you can safely omit it if you want as it has no effect on the functionality.

That's all there is to it. Tailwind CSS integration in SvelteKit in 3 easy steps. If I now counted correctly that is.