Coding, Insights, and Digital Discoveries 👩🏻‍💻

From Stay-at-Home Mom to a Developer After 50

Published on

Using Tailwind CSS to Enhance My Vanilla JavaScript To-Do List App

tailwindcss + vanilla Javascript

I started a project using vanilla JavaScript to build different versions of a To-Do List app.

Initially, I styled the project using pure CSS with classes and IDs, but I found it too time-consuming and difficult to maintain. To improve efficiency, I decided to integrate Tailwind CSS. I installed Tailwind using npm instead of a CDN because the CDN version cannot purge unused CSS, which can negatively impact performance as the app scales.

🚀 Step 1: Install Tailwind CSS via npm

Run the following commands in the terminal:

npm init -y  # Initializes a package.json file
npm install tailwindcss @tailwindcss/cli # tailwind v4.0 instruction doc

Following the Tailwind v4.0 installation guide, I created a file at /src/input.css and added this line @import "tailwindcss";

Then, I ran the following command to build the Tailwind CSS output:

npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watch

The final step was to include the generated CSS file in the <head> section of index.html: <link href="./dist/output.css" rel="stylesheet">

TIP

I chose to use a "dist" folder for dynamically generated files. To make things more convenient, I also added the build command to the package.json file. Since npm install generates a node_modules folder, I made sure to include it in the .gitignore file to prevent it from being pushed to GitHub.

🛑 TailwindCSS v4.0 lost VSCode Tailwind CSS Intellisense autocompletion

After installing Tailwind CSS v4.0, I noticed that VS Code's Tailwind CSS autocompletion had stopped working. This happened because Tailwind v4 no longer generates a tailwind.config.js file by default, but this file is required for the Tailwind CSS IntelliSense extension to function properly.

Following this solution, I created a tailwind.config.js file and added the following configuration:

/**  @type {import('tailwindcss').Config} */
export default {
    content: [
        "./index.html",
        "./src//*.{js,ts,jsx,tsx}",
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}

This configuration works for my To-Do List app's file structure, but you may need to adjust the content paths based on your own project structure.

Once I added this file, Tailwind CSS autocompletion started working again in VS Code. 🎉

❓ Some Tailwind Classes Weren’t Working—Why?

When I applied Tailwind CSS classes to my index.html file, some classes worked as expected, but others were missing. After some research, I learned more about how Tailwind CSS's purging mechanism works.

🔍 How Tailwind’s Purging Works

Tailwind CSS uses a build-time optimization process called purging to keep the final CSS file size small. By default, Tailwind generates thousands of utility classes. During the build process, it scans project files for class names and removes any unused classes from the final CSS output.

🛠 Fixing Missing Tailwind Classes

In my case, I had the following class in index.html:

<div class="mt-10 bg-amber-800 pt-10">

These styles weren’t applied because Tailwind hadn’t scanned and included them in the build yet. The fix was simple: rebuild the Tailwind CSS output. Since I had already added the build script to package.json, I could just run: npm run build-css in the terminal.

    "scripts": {
        "build-css": "npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watch"
    },

After rebuilding, Tailwind detected the new class names and included them in dist/output.css, making them work properly.

TIP

To avoid this in development: Keep the --watch flag active so Tailwind automatically rebuilds when changes are made::

npx tailwindcss -i ./input.css -o ./dist/output.css --watch

NOTE

For production: Always do a final build of TailwindCSS before deploying.

Integrating Tailwind CSS into my To-Do List app made styling so much easier, but it also came with a few unexpected challenges—like missing classes and broken IntelliSense. Figuring out these issues along the way wasn’t always fun, but honestly, that’s one of the best parts of coding. You run into problems, dig around for solutions, and by the time you fix them, you understand things on a whole new level.

For me, building projects like this is the best way to learn. Every bug I fix makes things click a little more, and each mistake turns into a chance to get better. Excited to keep improving this app and see where it goes next! 🚀

← See All Posts