This episode traces the evolution of web styling from monolithic CSS, preprocessors, and architecture patterns like BEM, to the birth of utility-first CSS. You'll also see a comparison of Tailwind with other approaches, its trade-offs, and a case study on migrating components from traditional CSS to utility classes.

Before understanding Tailwind techniques, it's important to understand why Tailwind exists. Episode 1 traces the journey of web styling: from monolithic CSS, preprocessors, and architecture patterns like BEM, to the birth of utility-first CSS. This historical context lets you appreciate Tailwind's design while also knowing when other approaches fit better.
Every technology is used because it solves the problems of its era. BEM and OOCSS solved the naming convention problem in large CSS codebases; CSS-in-JS solved the scoping problem; Tailwind solves the consistency and productivity problem. Understanding which problem each approach solves will guide your architecture decisions in real projects.
At the end of the episode, we'll look at a small case study: migrating a button component from traditional CSS to Tailwind utility classes.
In the early web, styles were written in one large stylesheet with element- and class-based selectors. As applications grew, files became hard to maintain, class names collided, and the cascade often became a source of bugs. Preprocessors like Sass and LESS helped with variables, mixins, and nesting, but they didn't solve the root problem: naming conventions and selector scalability.
Then came architecture patterns. OOCSS separated structure and skin, SMACSS divided rules into categories, and BEM enforced the block__element--modifier naming convention. BEM became very popular because it made CSS more predictable, but it demanded high discipline and produced verbose markup.
In 2017, Tailwind Labs released Tailwind CSS, led by Adam Wathan and the team. The core idea is simple: instead of giving components abstract names, provide small utility classes that map to a single CSS property, then combine them directly in your markup. This approach revolutionized how teams think about styling.
Utility-first is a styling strategy where small, focused classes — like p-4, flex, bg-blue-500 — are used directly to build UI, without writing your own component CSS. A comparison with traditional CSS:
<div class="card">
<h2 class="card__title">Kartu</h2>
</div>
<div class="rounded-lg border border-gray-200 p-4 shadow-sm">
<h2 class="text-lg font-semibold">Kartu</h2>
</div>Notice: in the utility-first version, there's no custom CSS to write or maintain. All declarations are generated by Tailwind from the classes used in the markup.
Traditional CSS separates styling from markup; Tailwind unites them. Traditional CSS wins when you need small files for simple cases, but Tailwind wins on consistency because you never write a new hex value — all colors and spacing come from the same design tokens.
BEM gives components descriptive names and is great for documentation, but long block__element--modifier names are often used only once. Tailwind eliminates the need for a naming convention altogether: style and structure live in one place, and there are no "orphan" styles — defined but never used.
CSS-in-JS like styled-components offers powerful scoping and runtime theming, but it adds JavaScript runtime to your bundle. Tailwind generates static CSS at build time — with no runtime at all. For performance-conscious applications, this is a major advantage; coexistence will be discussed in episode 18.
Tailwind's goals: productivity because you don't switch between files, consistency because tokens are centralized, and reduced custom CSS that tends to rot. The trade-offs to understand:
Info
The question "is utility-first good" usually misses the point. The right question: is the trade-off of verbosity for consistency worth it for your project. For most web applications, the answer is yes.
Imagine a button component with traditional CSS:
<button class="btn btn-primary">Simpan</button>With a separate stylesheet:
.btn {
padding: 0.5rem 1rem;
border-radius: 0.25rem;
}
.btn-primary {
background: #3b82f6;
color: #fff;
}Migrating to Tailwind removes the two CSS rules and moves everything into one markup:
<button class="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
Simpan
</button>The class hover:bg-blue-600 adds a hover variation without writing a single line of CSS. The value #3b82f6 is covered by bg-blue-500, so there are no more hardcoded colors scattered across files.
Episode 1 provided the historical context and the reasons why Tailwind CSS became the de facto standard of modern frontend development. You now understand the journey from monolithic CSS to utility-first, the differences between Tailwind and BEM and CSS-in-JS, the trade-offs to consider, and a picture of component migration.
Key takeaways:
Next, in episode 2, we'll dissect Tailwind's core concepts and main architecture — how the JIT engine and content scanning work, the structure of tailwind.config.js, the @tailwind base, components, utilities directives, up to the first official plugins you should know. This is the technical foundation before you write your first utility classes in episode 3.