A common misconception.
In reality Shadcn is a thin wrapper around libraries such as Radix, recharts, etc. The article says as much.
You're absolutely right!
Today I'm using a friends gaming computer. It's a 244hz monitor powered by a RTX 5070 TI and a screamingly fast AMD Ryzen 7 9800X3D CPU with 128GB of overclocked 6000MT/s RAM.
Not only does the radio look mundane for such overcomplicated component, but it also misses clicks where I would expect it to register. Like slightly above or below it.
For example, clicking where the pointer is in this image does NOT select the first radio button. It's not forgiving with regards to precision.
On a recent MBP, it's indistinguishable from a vanilla radio button.
According to who? This alone is a pretty damning case against such a claim.
It does seem the complexity was a deliberate decision.
The other half of it looks to come from an overloaded Label component which should probably have been split into two. There’s a reason that HTML has <fieldset> and <label> as different things. The implementation is also trivially incorrect: role=label isn’t a thing. Other parts of it are wrong or dubious too. In general, if the HTML way of expressing something isn’t permitted, the ARIA way of expressing the same thing is probably wrong too.
And so it goes, through the entire system. They assume you might want something ridiculously complex, and so they complicate and make worse the normal case.
I am 100% convinced that "Modern" front end developers are in fact, afraid of CSS and HTML. Like, "it will steal my eyeballs and look back at my face with them" scared.
Nothing else explains things like this, tailwind, JSX components, etc. Nothing. There is no explanation besides absolute morbid fear of the underlying technology - because the browser support has improved immensely but apparently they're all deathly scared of using it.
Before you tell me that I don't know what challenges these problems solve: I was primarily doing front-end development.... 20ish years ago. One of my first jobs in the space was adapting the client side code for a J2EE app - mostly this meant removing an IKEA worth of tables and using CSS - in IE6 of all fucking things. Subsequently I created reusable UI frontend components (i.e. output some HTML, maybe this little bit of corresponding JS, you'll get a usable interactive components in a browser) for two different organisations.
I have said it before and I'll say it again. I think JavaScript developers heard about (or saw over someone's shoulder) how J2EE guys had ant/etc build toolchains, and had abstraction like FactoryFactoryImplementationFactoryBuilderFactory and said HEY THAT LOOKS COOL, and if it's harder to understand they can't fire me!!
It's like NIH syndrome but for an entire community of people whose primary goal is chasing the shiny, followed closely by resume padding.
- Implement the radio as the designer sent in the figma file (e.g. something like the radix demo one they're commenting on: https://www.radix-ui.com/primitives/docs/components/radio-gr...)
- Make sure it looks the exact same across all browsers
How doable is it with vanilla css? The example they gave was rendered to a black/white circle, most teams wouldn't ship that.
Use this approach everywhere and the actual content of the page (you know: the stuff people came for) suffers.
All I can think about is a quote by world famous video artist Nam June Paik: When to perfect, Gott böse ("God gets mad when too perfect", the original isn't exactly a full sentence and mixes English and German).
I mean, a "colorful fat choncker" website is literally the opposite of fast food - its slower to arrive, and focuses way too much on appearances.
In this analogy, the website using these ridiculous abstractions is more like Salt Bae or whatever idiotic trend has replaced him. All glitz, zero substance, slower, and for no apparent reason.
The fast food equivalent is stuff like the Google home page: it doesn't validate, is actively harmful to you, the community, and the planet but is immensely popular.
input[type="radio"] {
appearance: none;
margin: 0;
width: 25px;
height: 25px;
background: white;
border-radius: 50%;
display: inline-grid;
place-content: center;
box-shadow: 0 2px 10px color(display-p3 0 0 0/0.5);
&::before {
content: "";
width: 11px;
height: 11px;
border-radius: 50%;
}
&:checked::before {
background: color(display-p3 0.383 0.317 0.702);
}
}
Here's a link to a codepen so you can see what it looks like without rendering it yourself: https://codepen.io/erikaja/pen/RNRVMyB > - Make sure it looks the exact same across all browsers
> How doable is it with vanilla css?
It's not doable with your fancy frontend framework and your 20 imports and your ten thousand lines of typescript."Make sure it looks the exact same across all browsers" is, and always has been, fundamentally at odds with how the web is intended to work.
How well does this shadcn crap render in arachne? ladybird? netsurf? links? dillo? netscape 3? The latest version of chrome with user styles applied?
When you say "exactly the same", I assume you mean that the design only uses black and white, because some people might have black and white monitors, right? But you're also going to use amber-on-black because some people might have amber screen monitors, right? How do you plan on ensuring it looks exactly the same on a braille terminal?
Maybe you think I'm being silly. Because nobody uses monochrome monitors in 2026, right? So it's safe to ignore that and put an asterisk next to "exactly the same" (And also just forget that e-ink is a thing that exists).
(Just like how it was safe in 2006 to assume people would always have 800x600 or bigger displays, and nobody would ever come along using a screen with, say, 480×320 resolution)
What measures have you taken to ensure that your colours appear exactly the same across a bunch of different types/brands of monitors that render colours differently? Or, perhaps we should just add another asterisk next to "exactly the same"?
I could go on.
How many asterisks is acceptable before "exactly the same" isn't a thing anymore?
If "exactly the same on all browsers" is one of your goals, you are wrong. If your designer tells you that's what they want, they are wrong. If you ever tell a client that's what you're providing, you are wrong.
https://www.radix-ui.com/primitives/docs/components/radio-gr...
Shoutout to Basecoat UI[1], so implementing the same components using Tailwind and minimal JS. That's what I am preferring to use these days.
in my anecdotal experience as a bit of an old fogey with a greying beard, the enthusiastic juniors come along, watch a video by some YouTube guru (who makes videos about code for a living instead of making actual software) proselytizing about whatever the trendy new library is, and they assume that it's just what everyone uses and don't question it. It's not uncommon for them to be unaware that the vanilla elements even exist at times, such is the pervasiveness of React bloat.
> I genuinely don’t understand how front-end developers accept this level of needless complexity.
I call it 'Shiny Object Syndrome' - Frontend devs tend to love the latest new JS frameworks for some reason. The idea of something being long running, tried and tested and stable for 5-10 years is totally foreign to many FE devs.
Despite its age JS and its ecosystem have just never matured into a stable set of reliable, repeatable frameworks and libraries.
For some reason people keep going back to complex UI and interactivity frameworks though, does anyone have a good example of a large website built without all this bloat?
Asking because I've seen hundreds of small sites built with elegance and simplicity, and few large ones. Is it just inevitable that as a team size grows, someone introduces insanity? Do these tools solve an actual problem that I'm missing?
The crux tho is that this usually happens in what id call web apps and not websitess. Web apps are far more complex and powerful. It is a spectrum tho and sometimes websites grow into web apps which is why people oft over engineer early on.
How about this one?
2022 post about it. 1400 points. ~500 comments:
No, obviously. If you are writing complex web applications with state, local processing of data and asynchronous interactions it's not enough. You need javascript. If your javascript is especially complex and you desire it to be declarative, you probably need a framework. Do you need, I don't know, Tomcat in Java? Probably yes for a complex application and no for a simple proof of concept. Do you need a database? Aren't files enough? And so on.
Shadcn is a framework for developers who develop highly interactive web apps. If all you need is a static form that submits data to a web service, you probably don't need a framework (except when you need it - for example, selects are not yet fully styleable in all browsers).
Next objection usually is: do you need complex apps on the client? Can't they be reduced to a series of simple forms controlled by the server? Sometimes they can and sometimes they can't, but of course I will decide the shape, behaviour, complexity and look of the applications I build (or have others build for me), thank you very much.
That said, radio buttons have been styleable in all non-legacy browsers for at least 5-6 years, there's no excuse for rewriting them from scratch with svgs.
OP, I think your being a bit hasty here, more curiosity will do you good.
As it is, you've joined the ranks of multiple others commenters who sound like cargo cultists, attacking OP for not understanding frontend dev without actually pointing out any issues in their writing. If it's easy to point out, then surely you can show how easy it is.
We’re like 20+ years into web apps being a big thing and there’s still nothing like what’s offered in OS-native frameworks like Swift.
So anybody building a web app has to recreate SwiftUI in the browser every time via various bloated hacks (basically what Shadcn is).
If we could just agree on adding non-terrible cross-browser primitives for multiselect, popovers, modals, proper radio buttons, tabs, etc to the HTML spec and allow extensive CSS styling on every part of the element we could avoid these massive UI frameworks.
I've watched teams spend weeks just getting comfortable with component library internals before they can be productive. Meanwhile the "simpler" vanilla approach might have taken an afternoon to build but takes 20 minutes to explain.
That said, if you're building something like Figma or Linear where you genuinely need the accessibility primitives and keyboard navigation that Radix provides, the complexity pays for itself. Most CRUD apps don't need it though.
Unlike other abstractions where things get tidied up and more simple, React is much more complex than the technology it's building on. Necessarily, to enable it's features, but none the less it is a consequence of this that when all someone knows is React or other frameworks, things get overengineered. They didn't realise it could be so much simpler if they just knocked it back a layer instead of climbing higher and higher.
If you need to be an app you usually need a framework to stay sane (evidence: most other native UI kits are frameworks of some sort) and thus React etc. But they want full contol. Thus 2 ways to do a radio etc.
I assumed I would need to use one of these libraries at some point. But, perhaps since I am using Svelte instead of React, whenever I ask AI to do something, then since I don't already use a component lib it just spits out the HTML/CSS/TS to do the job from scratch (or, depending on how you look at it, output the mean component from its training data).
I have to point out it should organize the code and give the component a dedicated Svelte file (sure I could fix AGENTS md to do that).
I think with AI the usecase for these libraries is much lower. If there is anything complex you need AI can build it in some seconds specifically tailored for you, so..