Component Is a Vegetable Word

A tomato with a paper tag tied to its stem that reads 'NOT A VEGETABLE,' against a mustard-yellow background.

Vegetables don’t exist, at least not as a biological category. I first heard this argued, half-jokingly, in a Dropout comedy bit. Botanically, a tomato is a fruit, a potato is a tuber, and spinach is a leaf. Vegetable was a classification coined in the medieval era to describe anything in the plant kingdom, later narrowed to mean edible plants grown specifically for human consumption. It’s a word that groups things by how we eat them, not by what they structurally are. It works fine at the grocery store, as nobody needs botanical precision to make good soup.

Design has its own version of “vegetable,” and it causes as much damage as putting a tomato in a fruit salad. That word is “component.”

Ask five people on a product team what a component is and you’ll get all different answers. Something simple, something complex, an instance or even a whole template someone decided to call a component because it gets reused. All those answers are correct, but none of them are talking about the same thing. This isn’t a sign that people are careless, it’s just that the word never described a fixed unit to begin with.

While it may not seem all that harmful, that imprecision has a real cost in my perspective as a designer.

I ran into this directly while building text, select, and password fields that shared the same visual specs in Figma. Same border, padding, typography, same everything. To me it was obvious, with a little bit of work to think about variables we would need only one component instead of three. My frontend developer disagreed, and he was right to. The three fields carry different behaviors, accessibility requirements, ways of receiving and returning a value, etc. Using the same token or style is fine, but sharing an identity is a totally different thing.

Diagram showing two design tokens, Status and Foreground, that produce almost identical visual output but are kept as separate tokens because they serve different semantic purposes.

Status and Foreground are visually similar tokens that render almost the same way, but keeping them separate avoids forcing one name onto two different jobs.

Diagram showing two design tokens, Texts and Icons, that produce almost the same visual output and were merged into a single token named Foreground because their use case fully overlaps.

Texts and Icons, on the other hand, always serve the same purpose, so they were merged into a single token: Foreground.

As my developer put it, the styling can be identical, but the component underneath is essentially different.

The gap wasn’t vocabulary, per se. It was what “component” was being used as in our conversation. On the design side, it often means a visual and structural unit: how something looks, how it composes, what states it supports. On the engineering side, it means a unit of behavior: what it does, what contract it exposes, how it fails. Here’s where the analogy gets precise. It’s the same imprecision buried in the root of “vegetable.” A cook uses it for anything edible and plant-based. A doctor uses the same root to describe a patient in a vegetative state, unresponsive and without awareness. Both usages are real, both are correct within their field, and they have almost nothing to do with each other. The word was never built to survive both jobs at once.

Once that gap between roles is visible, the tempting fix, from the design perspective, is to add more components with more instances and states. Which in our case, would mean going from one component to three. Three times the naming, documentation, and future reconciliation to maintain, for a difference that lived in behavior, not in how the fields looked. So, instead of growing the component’s structure, we introduced boolean properties to toggle those variations and kept the larger, less common cases as standalone examples living outside the component. Our component stayed lean and legible, instead of quietly turning into a library of near duplicates. My developer, meanwhile, kept seeing three distinct pieces of behavior in the code, and that was fine. We didn’t need to share the same definition of component. Each of us had a correct answer inside our own domain. Mine measured by maintenance and legibility, his by behavior and contract. What we needed was to see eye to eye on which domain’s “correct” governed this decision, even if it meant staying misaligned, each of us following our own “correct,” and to document it so nobody down the line mistook it for an accident.

That’s the difference between a library and a grammar. A library is a wall of shelves: you grab the book you’re looking for and that’s it. A grammar is a set of rules with a lot of reasonably strong exceptions, and someone has to keep track of which is which. Taking care of that means thinking about maintenance, documentation, and reconciliation with the rest of the system. Not developer versus designer this time, but builder versus anyone who just needs the component to work. We, system builders, have to ask a different question than the people who consume it. The consumer asks “does this solve my case right now.” The builder has to ask “what does saying yes to this case cost everyone else, later.”

For most people using a design system, calling it a library isn’t wrong. That’s what it should feel like to use. But for those of us who build and maintain it, treating it as only a library is exactly what produces the ambiguity everyone else eventually runs into. The word “component” behaves the way it does for a similar reason “vegetable” does. Both are convenience labels, built for how something gets used, not for what it structurally is. That’s not a flaw in either word. It’s two correct answers refusing to share a frame. Every time someone says “component,” somebody still has to ask which job it’s doing in that sentence: shorthand for how something looks, or a contract for how something behaves. The answer is what decided how many components were enough in my example. One, not three.

In the end, nobody gets hurt calling a tomato a vegetable at the grocery store. The damage only shows up at the table, when someone serves you a fruit salad with a tomato on it.

Gustavo Carneiro

Gustavo Carneiro

Senior product designer and systems thinker, currently at KTO.