Learning React - Part 2: Using Tailwind CSS


This post follows on from part one where I just downloaded the essentials for creating a barebones React app. This post will be about React itself, kind of, but mainly about installing TailwindCSS.

How to run stuff

If you are unfamiliar with using npm to run apps, or you miss the play button that Visual Studio provides, you can open up the package.json file.

In it you will see a bunch of dependencies as well as a scripts section. For example in order to run the linter you need to run the command:

 npm run lint

This will execute the eslint at the current directory location. It is a wrapper for running something like:

 npx eslint .

The more observant of you will notice that the shorthand is not shorter, but it does simplify what you need to run by ensuring it’s always

npm run X

where X is the name of the script in the package.json.

The main command you will be using is likely

npm run dev

Index.html

React is commonly used to build a single page application (SPA). This project I will be writing is going to be a SPA, and therefore there is only one HTML page, although it will eventually appear as though there are multiple pages.

This is the index.html page you will be presented with on first scaffolding out a new React project:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

The browser loads the HTML pages and then everything else is loaded via JavaScript from this as a module type:

<script type="module" src="/src/main.tsx"></script>

In SPAs the entry point of the app is the Main.tsx file which will get loaded into this div in the index.html:

<div id="root"></div>
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render
(
  <StrictMode>
    <App />
  </StrictMode>
)

The React DOM will create the root of the application by grabbing the div using old-school javascript and render the App component.

Styling the App

If you run your React program now you will see that it doesn’t look like an unstyled HTML page. It will have the Vite and React logos, some animations, some gradients etc. That’s because the app is already using CSS as part of the template setup.

You can remove the App component from the Main.tsx file and replace it with some normal HTML and it will still appear styled:

createRoot(document.getElementById('root')!).render
(
  <StrictMode>
    <h1>Zero Point Empire</h1>
    <p>A game without a point</p>
  </StrictMode>
)

I mean, it doesn’t look great, I didn’t say that it would, but styles are still being applied. But we don’t want those styles, we want to use a CSS framework instead.

To that end we will install Tailwind CSS. We’re using Vite so you can just go to this part of the TailwindCSS site and follow the steps, but I’ll write them out here anyway.

Step 1: Install ’tailwindcss’ and ‘@tailwindcss/vite’ via npm:

npm install tailwindcss @tailwindcss/vite

Step 2: Add the @tailwindcss/vite plugin to your Vite configuration (vite.config.ts):

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' // <--- add this

export default defineConfig({
  plugins: [
    react(),
    tailwindcss(), // <--- add this
  ],
})

Step 3: Import Tailwind CSS to your css file:

The React app will have two CSS files already, App.css which is used to style the App component, and index.css which is used as a base CSS throughout the whole application.

Delete the App.css file and remove everything from the index.css, replacing the contents of index.css with just:

@import "tailwindcss";

Finally remove the line:

import './App.css'

from App.tsx, as there is now no longer an App.css to import.

Step 4: Check if it works:

Run the application with:

npm run dev

and look at the now-terrible app:

Good job, looks shit. That means we are making progress1.

Now just make some changes to the App.tsx and remove all that boilerplate stuff and add some of your own junk to test this Tailwind setup:

function App() {

  return (
    <>
    <h1>Zero Point Empire</h1>
    <p>A game with no point</p>
    </>
  )
}

export default App

Now to run the app again, and:

Looks shit.

Well, that’s because we haven’t added any Tailwind classes yet, so let’s do that:

function App() {

  return (
    <>
    <h1 className="text-5xl">Zero Point Empire</h1>
    <p className="text-3xl">A game with no point</p>
    </>
  )
}

export default App

Now run that app again, and:

Still looks shit.

Yeah.

Progress 🚀

Stay tuned for part three where I might even talk about React!

« Back to Posts | « Back to Part One

21st April 2025


  1. An example of the kind of lie I tell myself each passing day ↩︎

Serigan's Blog