The Problem With Rebuilding Components From Scratch Every Time
I spent about four years working on a design system that started small enough to manage by hand and grew into something that could no longer be tracked in any spreadsheet or mental model. Every time a new designer added a variant, we ended up with duplicate markup, conflicting styles, and a CSS file that was roughly 800 kilobytes of unoptimized rules. This is what happens when you stop thinking about structure early enough. The Nicole Sullivan Method How One Architect Redefined Scalable UI Systems gives you a vocabulary that prevents most of those problems before they start. Nicole Sullivan wrote about a naming convention called Block, Element, Modifier while working on large Yahoo properties around 2008. She needed a way to keep styles from bleeding across components as the codebase grew. The approach breaks down into three parts. A block is a standalone component with no parent dependencies. A element is a piece of that block with no independent meaning outside it. A modifier changes the appearance or state of either a block or an element. The resulting class names look like .card, .card__title, .card--featured. That is all there is to the core idea. The rest is discipline. Most developers I have worked with think BEM is just a styling convention. It is not. It is a structural constraint that forces you to think about component boundaries before you write CSS. When you name classes this way, you immediately see whether something is truly independent or whether you have accidentally created a nested component without defining it. I once inherited a button system where every variant had its own class like .btn-save, .btn-delete, .btn-export. Each one carried slightly different padding, margin, and hover states. We were maintaining roughly fifteen copies of the same layout logic. Rewriting them under the BEM approach took about two days and reduced the button-related stylesheet from 340 lines to about sixty.
The most common mistake is treating modifiers as a catch-all for every possible variation. You will see codebases where someone creates .card--light, .card--dark, .card--compact, .card--with-image, .card--hoverable. This is not scaling. This is just renaming the problem. Modifiers should only express meaningful state or variant changes, not every permutation of props. If you find yourself naming classes that describe a specific data value, you are usually doing it wrong. A modifier like .card--has-image makes sense if the component has a well-defined optional section. A modifier like .card--has-user-avatar-from-sales-team does not. Another thing that catches people off guard is the relationship between BEM and CSS-in-JS or component frameworks. BEM was designed for plain CSS, but the underlying idea applies regardless of your styling approach. The naming discipline remains useful even in Tailwind or styled-components, because it keeps your mental model of what is a block, what is a sub-component, and what is a state change intact. Some teams I know use BEM-style names only in their component library documentation while relying on CSS modules under the hood. That works. The convention is about clarity, not about forcing a specific tool.
A Real Edge Case I Dealt With
Once I ran into a situation where a single block needed two independent modifier chains active at the same time. We were building a notification system where messages could be both dismissible and urgent, and we also had a compact display mode. The naive approach would have produced classes like .notification--dismissible-urgent-compact. That is already ugly and unmanageable. The actual fix was simpler than most people expect. You chain multiple modifier classes on the same element. The final markup looked like .notification.notification--dismissible.notification--urgent. CSS specificity handled the rest as long as you ordered your rules correctly. The compact variant was a separate block altogether because it changed the overall layout enough to qualify as a distinct component. Defining when one thing is a modifier versus when it is a new block took some friction to get right, but after the third or fourth decision, the pattern became obvious. If a change affects only appearance or behavior within the existing layout, it is a modifier. If it changes the layout structure or introduces a new set of sub-elements, it is a new block. BEM does not solve everything. It assumes your team agrees on component boundaries. If three people on your team have three different definitions of what a card is, BEM will not help you. You will end up with .card blocks that are structurally incompatible despite sharing the same name. It also does not help with design decisions. You still need a real design system, tokens, and guidelines. BEM is a naming convention, not a design strategy. Another limitation is that it adds verbosity to your HTML. .btn.btn--primary.btn--large.btn--icon-left is harder to read at a glance than some modern alternatives. If you are working on a project where developer experience in templates matters more than CSS namespace safety, you might prefer CSS modules or utility-first approaches. None of those are wrong. They just solve different problems. BEM excels when you are maintaining a large, long-lived codebase with many contributors who may not be deeply familiar with the styling layer. You do not need to rewrite your entire codebase to use this method. Pick one component type and define its block, elements, and modifiers explicitly. Write down the conventions in a single document so other developers know what counts as a modifier. Avoid creating modifiers for things that are really just conditional rendering. If a section only appears when certain props exist, handle that in the component markup, not with a modifier class. Keep your modifier list short. If you reach more than five modifiers on a single block, pause and ask whether you are building a component or a configuration object. The latter usually deserves a different architectural approach.
Get the Full Details

The reason this method stuck around for nearly two decades is that it addresses a real pain point. Component proliferation without naming discipline produces CSS that is impossible to audit. Every project I have seen that adopted BEM early and kept it consistent reported fewer style conflicts and faster onboarding for new developers. It is not a magic solution. It is a way to make your decisions explicit so nobody has to guess what a class name means three months later.