# TailwindCSS meets Express: A guide to effortles styling with pure JavaScript and without extra frameworks

I’m a big fan of keeping things simple. When it comes to building web applications, I tend to stick with technologies I know and trust. For years, I’ve relied on the combination of the Express JavaScript framework and Bootstrap for styling. It’s a reliable duo that gets the job done.

However, I’ve faced one recurring challenge: Bootstrap themes. While the framework is great, creating visually appealing themes from scratch isn’t my strong suit, and finding the perfect pre-made theme can be time-consuming.

That’s when I decided to explore alternatives. After some research, I landed on **TailwindCSS** - and I was immediately impressed. The websites built with TailwindCSS looked stunning, so I decided to give it a try.

### **A different philosophy**

The first thing I noticed is that TailwindCSS works differently from Bootstrap. Let me explain:

* **Bootstrap** is primarily a layout system. While it offers predefined components, you still need to write your own CSS to customize things like colors, typography, or specific UI elements.
    
* **TailwindCSS**, on the other hand, uses "utility-first" CSS. It provides small, reusable utility classes that let you style elements directly in your HTML.
    

For example, with Bootstrap, you might start with a predefined button component and then add custom styles for size, colors, or corners. With TailwindCSS, you can define everything directly in the HTML by chaining utility classes. Need rounded corners, larger text, and a custom color? You simply add the relevant classes, and you’re good to go.

### **The power of TailwindCSS**

Because TailwindCSS relies on utility classes, your CSS output can grow quite large. To solve this, Tailwind introduced a **just-in-time (JIT) compiler**. This tool generates only the CSS your project actually uses, based on your code, templates, and views.

That’s where things get interesting. Unlike Bootstrap, where you simply include the full CSS file in your project, Tailwind requires a build process to compile and optimize your CSS. This makes Tailwind a popular choice for modern frameworks like Vue, React, and Next.js.

But what if you’re not using those frameworks?

### **TailwindCSS with Express and pure JavaScript**

I still prefer to keep things simple and stick with Express. So, I dug into the possibilities of using TailwindCSS without any additional UI frameworks. To my delight, it’s not only possible but also straightforward!

There are a few articles on this topic, but none I found provided detailed steps or worked correctly on the first try. In this guide, I’ll walk you through how to set up TailwindCSS in your Node.js project using pure JavaScript and Express. No Vue, no Next.js - just simple, effective styling in your familiar setup.

Ready to modernize your styling game while keeping your workflow simple? Let’s get started!

### **Step 1: Setting up your project**

1. **Create a Node.js Project**  
    Start by creating a new Node.js project. Navigate to your project directory and run:
    
    ```bash
    npm init
    ```
    
    For the entry point, I typically name the file `server.js`.
    
2. **Install dependencies**  
    Next, install the necessary packages:
    
    * [Express](https://expressjs.com/) - Web framework for Node.js
        
    * [EJS](https://ejs.co/) - Templating engine for Express
        
    * [TailwindCSS](https://tailwindcss.com/) - CSS framework
        
    * [@tailwindcss/postcss](https://tailwindcss.com/docs/installation/using-postcss) - TailwindCSS plugin
        
    * [PostCSS](https://postcss.org/) - CSS transformation tool
        
    * [PostCSS CLI](https://www.npmjs.com/package/postcss-cli) - Command-line interface for PostCSS
        
    * [Autoprefixer](https://www.npmjs.com/package/autoprefixer) - Plugin for adding vendor prefixes to CSS
        
    
    Install them with the following command:
    
    ```bash
    npm install express ejs tailwindcss @tailwindcss/postcss postcss postcss-cli autoprefixer
    ```
    
3. **Set up the project structure**  
    Create the following files and directories:
    
    * `server.js` - Your main server file.
        
    * `assets/` - Directory for static files like styles and images.
        
    * `assets/css/` - Subdirectory for CSS input and output files.
        
    * `views/pages/` - Directory for EJS templates.
        
    
    Your project structure should now look like this:
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1737988080095/5a833edd-7c7f-4673-be51-4aa11e298ac1.png align="center")

1. **Write the Express server code**  
    Add the basic Express configuration to `server.js`:
    
    ```javascript
    const express = require('express');  
    const path = require('path');  
    
    const app = express();  
    const port = process.env.PORT || 3000;  
    
    // Set up EJS  
    app.set('view engine', 'ejs');  
    app.set('views', path.join(__dirname, 'views'));  
    
    // Serve static files from the 'assets' base directory
    app.use(express.static(path.join(__dirname, 'assets')));  
    
    // Define the root endpoint  
    app.get('/', (req, res) => {  
        res.render('pages/index', { title: 'TailwindCSS with Express!' });  
    });  
    
    // Start the server  
    app.listen(port, () => {  
        console.log(`Server is running at http://localhost:${port}`);  
    });
    ```
    
2. **Add the initial EJS template**  
    Create an `index.ejs` file in the `views/pages/` directory and add a basic HTML5 structure:
    
    ```html
    <!DOCTYPE html>  
    <html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <meta name="viewport" content="width=device-width, initial-scale=1.0">  
        <title>TailwindCSS with Express!</title>  
    </head>  
    <body>  
        <!-- Your content will go here -->  
    </body>  
    </html>
    ```
    
    At this stage, starting the server with `node server.js` will display an empty HTML page.
    

### **Step 2: Configuring TailwindCSS**

Now, let’s set up and configure TailwindCSS in your project.

1. **Create required files**  
    Add the following files to your project:
    
    * `tailwind.config.js` - TailwindCSS configuration file.
        
    * `postcss.config.mjs` - PostCSS configuration file.
        
    * `assets/css/tailwind.css` - CSS file to import TailwindCSS into your project.
        
2. **Set up** `tailwind.config.js`  
    Add this content to the `tailwind.config.js` file - import Tailwindcss configuration and specify location of the files containing CSS:
    
    ```javascript
    /** @type {import('tailwindcss').Config} */  
    module.exports = {  
        content: ['./views/pages/*.ejs'],  
        theme: {  
            extend: {},  
        },  
        plugins: [  
            {  
                tailwindcss: {},  
                autoprefixer: {},  
            },  
        ],  
    };
    ```
    
    > **Tip:** The `content` property specifies where TailwindCSS should look for classes. Update the path to match the location of your EJS templates. Use glob patterns to include multiple directories or files if needed.
    
3. **Set up** `postcss.config.mjs`  
    Add this content to the `postcss.config.mjs` file:
    
    ```javascript
    export default {  
        plugins: {  
            "@tailwindcss/postcss": {},  
        },  
    };
    ```
    
    > **Note:** Since the project isn’t configured to use ES modules by default, the file must have a `.mjs` extension. If you enable `"type": "module"` in your `package.json`, you can rename it to `.js`.
    
4. **Set up** `tailwind.css`  
    In the `assets/css/tailwind.css` file, import TailwindCSS with this simple line:
    
    ```css
    @import "tailwindcss";
    ```
    
5. **Add a build script**  
    Configure a script in `package.json` to generate the CSS file:
    
    ```json
    "scripts": {  
        "tailwind:css": "postcss assets/css/tailwind.css -o assets/css/style.css"  
    }
    ```
    
    This script compiles TailwindCSS classes used in your EJS templates into a single `style.css` file located in `assets/css/`.
    
6. **Generate the CSS file**  
    Run the following command to build your CSS file:
    
    ```bash
    npm run tailwind:css
    ```
    
    This will create the `style.css` file in the `assets/css/` directory, which contains all the necessary CSS for your project.
    
    By now, your project structure should resemble the following layout:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1737988944857/e66de162-58da-4c18-97fe-a1d2501e748d.png align="center")
    

### **Step 3: Using TailwindCSS in EJS templates**

To start using TailwindCSS in your EJS templates, follow these steps:

1. **Include the CSS file**  
    Update your `index.ejs` file to include the compiled `style.css` file. Add this line to the `<head>` section:
    
    ```html
    <link href="./css/style.css" rel="stylesheet">
    ```
    
    > **Note:** You don’t need to include `assets` in the path because it’s already set as the base directory for static files.
    
2. **Add TailwindCSS classes**  
    Let’s style a simple `div` using TailwindCSS classes. Add the following block to your `index.ejs` file:
    
    ```html
    <div class="text-fuchsia-600 text-center py-10 text-2xl">  
        Hello, TailwindCSS!  
    </div>
    ```
    
    This will make the text fuchsia, center it, add padding to the top, and increase the font size.
    
3. **Rebuild and restart**  
    To see the changes, you’ll need to:
    
    * Rebuild the CSS file:
        
        ```bash
        npm run tailwind:css
        ```
        
    * Restart the server:
        
        ```bash
        node server.js
        ```
        
    
    After restarting, open the app in your browser to see the styled text.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1737988976131/a162a25f-6634-45c3-a5b4-2a9b8065c2ba.png align="center")
    
4. **Streamline the development workflow**  
    For a more convenient workflow, add scripts to your `package.json` to combine tasks. Update the `scripts` section with the following:
    
    ```json
    "scripts": {  
        "start": "node server.js",  
        "tailwind:css": "postcss assets/css/tailwind.css -o assets/css/style.css",  
        "serve": "npm run tailwind:css && npm run start"  
    }
    ```
    
    Now, running `npm run serve` will build the CSS and start the server in one step.
    

### **Optional: Enable auto-restart with nodemon and live CSS updates**

To further streamline development, you can set up two tools:

* **Nodemon** to automatically restart the server when changes are made.
    
* A **PostCSS watch option** to recompile CSS whenever files are updated.
    

#### **Step 1: Install nodemon**

Install Nodemon as a development dependency:

```bash
npm install --save-dev nodemon
```

#### **Step 2: Update scripts in** `package.json`

Add the following scripts to your `package.json` file:

```json
"scripts": {  
    "start": "node server.js",  
    "tailwind:css": "postcss assets/css/tailwind.css -o assets/css/style.css",  
    "serve": "npm run tailwind:css && npm run start",  
    "tailwind:css-cont": "postcss assets/css/tailwind.css -o assets/css/style.css -w",  
    "serve-cont": "nodemon server.js"  
}
```

Here’s what these scripts do:

* `tailwind:css-cont`: Runs PostCSS in watch mode (`-w`), which automatically recompiles the CSS whenever files change.
    
* `serve-cont`: Uses Nodemon to restart the server automatically whenever server-side code changes.
    

#### **Step 3: Run scripts in parallel**

Start both scripts to enable live updates:

1. Run the CSS watch script:
    
    ```bash
    npm run tailwind:css-cont
    ```
    
2. Run the server watch script:
    
    ```bash
    npm run serve-cont
    ```
    

#### **How it works**

* Any changes to your EJS templates or other files using TailwindCSS classes will trigger the CSS file to rebuild automatically.
    
* Updates to the server code will restart the server without requiring manual intervention.
    

With this setup, your development cycle becomes much faster and more convenient. Changes to your project will be visible immediately in the browser.

### **Conclusion**

Congratulations! You’ve successfully set up TailwindCSS in your Node.js project using Express and pure JavaScript. You can now leverage the power of TailwindCSS to style your web applications without the need for additional frameworks.

A quick recap of the required steps:

* Set up the project structure: Create the necessary directories and files for Express.js and TailwindCSS integration
    
* Install dependencies: Add Express.js, TailwindCSS, PostCSS, and supporting plugins to the project
    
* Configure TailwindCSS: Set up TailwindCSS and PostCSS configuration files
    
* Generate and include styles: Compile TailwindCSS into a usable stylesheet and linked it in the EJS templates
    

The complete source code is available in the examples directory on GitHub: [https://github.com/keenthinker/blogpostscode](https://github.com/keenthinker/blogpostscode).
