The Overcomplexity of the Shadcn Radio Button

paulmakeswebsites.com

386 points by dbushell 7 hours ago


ehnto - 5 hours ago

I don't touch frontend very often anymore, but you could see the writing on the wall for complexity when React took over and newer devs were working exclusively in that abstraction.

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.

benrutter - 6 hours ago

This radio selection is brilliant silly, especially because the end result is indecipherable from a vanilla css rqdio button.

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?

yen223 - 4 hours ago

This is the kind of stuff we have to do because almost all browser <input> elements are terrible in terms of customisability. Especially radios and selects

If you're one of those who think we should just use the default, bear in mind that the default radio button has poor usability for mobile users.

neya - 6 hours ago

I have absolutely no doubt that somehow all these projects and similar ones - started with good intentions - good looking UI, implement and forget. And then, one fine day you're sitting on top of 200+ lines of code for a radio button and 7 imports and it's too hard to go back now without tearing the whole codebase apart. This is how code rot starts.

ponyous - 2 hours ago

Developers remember, you can always push back on design requirements instead of bringing in more bloat.

I was sitting next to one of the devs in a co-working space and he was trying to figure out some specific layout issue in react native. He spent 4 hours + installed a dependency to be able to do something completely tiny on a privacy policy screen. He asked me how I would do it, I told him to just ask if it can be laid out differently. He got it approved and implemented in 10 minutes. No bloat.

jackfranklyn - 5 hours ago

The real cost of this complexity isn't the code itself - it's onboarding. Every new dev joining the project has to understand why a radio button needs 47 lines of JSX with Radix primitives, context providers, and styled variants.

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.

parhamn - 6 hours ago

I normally share the sentiments of the article. But I am also curious, if the goal was:

- 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.

adithyassekhar - 2 hours ago

The biggest mistake I did in 2025 was picking shadcn because it was so hyped. Saw it importing from radix anytime you enter a command. First red flag. Then I saw the radio component. Second red flag. You should see what they've done with the select component. But we were too far into the deadline for a project with running targets. So I just gave up and asked copilot to make the changes for me, and I'm not a fan of AI anything.

Funny enough we did a POC for the same project before that without shadcn and looking back, it's so much leaner and easier.

I might just break one night and redo the whole ui library with vanilla html elements.

CommonGuy - 3 hours ago

I recently tried out https://daisyui.com/ (CSS only components, depends on tailwind) and so far I really like it.

It also highlights how far browser have come with new features such as dialogs, which I always implemented with (a lot of) JavaScript in the past

Surac - 6 hours ago

Im not in web development. Reading this article makes me think: is it realy neccersary to use all those complex frameworks? Isn't html/css enough? People always say "every line not written can't be a bug" but moving those lines into a library was not the idea behind the words

mastermedo - 6 hours ago

The shadcn radio button in action: https://ui.shadcn.com/docs/components/radio-group

elias1233 - 2 hours ago

These comments don’t seem to have that much love for shadcn, which is unfortunate as I think it promotes good component file structure and reuse. The premise is that you could (and should) change the components yourself, as they are living in your code base and ”owned” by you, which is a radically different approach compared to other ui libraries.

xearl - 6 hours ago

Did they ask the original authors of Radix why it's the way it is?

jwr - 5 hours ago

Incidentally, radio buttons are a (sadly) forgotten art and are neglected in modern browsers. There are many issues with them, which is why people reimplement them on their own.

harel - 23 minutes ago

I evaluated a LOT of UI toolkits for React. The premise is always great - I want to save time by not having to build a UI toolkit for my application, so I'll use a great one off the shelf. But what I found was that the evaluation falls into three questions:

1. Does it look nice and professional?

2. Will it be here tomorrow?

3. How does it feel to work with - what does my instinct say?

The first question is easy. I either like it or not. I can't answer the second one with certainty. Nobody can. I can only guess. Sometimes I'm wrong.

The third one is instinct driven. If the ergonomics feel off, my instinct will tell me. If something is not right, I'll feel it. I might not always be able to explain it, but I'll know it's a go or no go. ShadCDN came with big praise, but my instinct said a big Nope. It's stuff like that that make me think that, maybe, we add complexity because we get bored with the "boring" tech.

tmvnty - 3 hours ago

So for a React developer who doesn't want to include Shadcn/Radix, but also doesn't have time to build every component/a11y/compat/edge cases from scratch, what are the better alternatives?

Would be nice to list them here so developers can know a midpoint between DIY <-> Shadcn/Radix

yalue - 2 hours ago

15 years ago, Enterprise FizzBuzz [1] was supposed to be satire. These days, it's not quite complex enough to capture "modern" web dev.

[1] https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...

mcintyre1994 - 4 hours ago

I think this is the equivalent of the radix demo (which has better styling than the shadcn one) in plain html/css: https://codepen.io/mcintyre94/pen/pvbPVrP

Copied styles from the radix docs: https://www.radix-ui.com/primitives/docs/components/radio-gr...

PlatoIsADisease - 2 hours ago

I see this with a bunch of python libraries too.

I imagine for some usecase, they are valuable. However, when reading advice on the internet you get comments from people that tell you what technology they used without consideration of the overhead required to use this technology and the problem at hand.

sceptic123 - an hour ago

Interestingly Radix has both `Radio Group` and `Radio` — The simple `Radio` input does use `<input type="radio">` but the `Radio Group` does not. Git history does not show _why_ though.

tekkk - 3 hours ago

Well I want to give shadcn some credit, building a comprehensive open-source UI toolkit, on your own basically, isn't as easy as one would think. Yeah you can use native elements except for some tiny edge case with say Safari and then you go deeper into the rabbit hole, until you decide you'll just customize everything. But at this point you probably have lost a lot of time and sanity already.

I'd put the blame on React and poor Web APIs in this case. Both are way too complicated for mere mortals to understand fully, and even simplest things like maintaining 100% container height through nested elements, can become a ridiculous time-sink for something completely unrelated to what is your main objective.

ediatedia - 5 hours ago

Ok, I'll bite. I've been coding for almost 25 years so have seen various things come and go, so hopefully have a bit of capital in the bank.

Don't get me wrong, a HTML5 radio button is a beautiful thing, and sometimes React is a hammer and everything is a nail.

However, I think something that OP doesn't mention super explicitly in their post is the codebase they are working on is probably a React codebase. React is a great abstraction for building UIs. I've built a ton of them and the complexity only needs to go above a certain degree until you need a way more descriptive way of explaining your UI based upon other state, instead of trying to wire a load of DOM elements together.

If you are already using the React ecosystem, for things like form validation (again, possible with HTML5 but as soon as the complexity cranks or you can't use the server - you probably need a library), then using something like Radix is a great choice, OP even mentions how although it's not technically a visible radio button that is shipped to the DOM, it acts like one for a11y reasons, and this is due in part because it's very, very easy to write inaccessible HTML. And ShadCN is pre-made components on top of that, and they all work pretty well together.

Nothing is perfect, but even in my "old man yells at cloud" era, I personally don't think this one is worth yelling at the cloud for.

- 6 hours ago
[deleted]
cadamsdotcom - 4 hours ago

A html forms based radio button is worse than a complex - but standard - shadcn radio button many ways that matter in the real world.

Why does no one do the simpler thing? Because there’s no extra value to it, and it in fact has negative value because then the team has to write and understand it and the rationale for the departure from just using the same component library everywhere.

“Only a few kb of javascript” may as well ZERO javascript, and because of that it’s not even close to the top thing to optimize on your favorite site.

So, you engineered a non-standard radio button that is different to the rest which all use shading?? Why weren’t you building features that you know.. make money?

worldsayshi - 6 hours ago

Well Shadcn gives you more freedom to fix stuff like this and rewrite how you want the component to work and look, since everything lives in your own code base. In a regular component lib it would be less likely that you'd think about this complexity, since it would be "hidden" away in node_modules or even transpiled and minified.

dagss - 5 hours ago

I am pretty new to frontend development (but have 20 years of backend)

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..

bromuro - an hour ago

I don’t see the “complexity” the author is yelling about. Maybe is the tailwind verbosity?

It seems they don’t understand the underlying requirements when building a reusable UI library. Yes in shadcn there are some opinionated choices , but the “i can do better/ i am smarter” attitude of this article is off putting.

We used shadcn in one project , and wrote a custom UI library for another (using the same “smart trick” for input elements). Shadcn wins for clarity, consistency, maintenanility and simplicity.

librasteve - 2 hours ago

> Look at it. It's beautiful.

Quite right too … I’m choosing HTMX over React for just that.

Piraty - an hour ago

> Web development is hard.

no it's not.

you all make it hard by bloating your sites with Jenga tower abstractions for styling, needlessly load content dynamically via Jenga tower javascript libraries that pulls complexity into frontend and most of the time puts unnecessary load on the content generator ("backend") too. I don't know a lof of sites where that actually makes sense, as web === text.

When html5 came about, along with CSS3, it was such a big leaf in terms of ease of use and accessibility. I argue that what most websites do to my taste nowadays can be achieved by early-stage html5+css3+ a few svg.

Nowadays on about 50% of websites it have to * enable 3rd-party JS just to get the text * enable massive amounts of 3rd-party JS to get the images * enable remote fonts just to grok your pathetic icon-only menu or even spot the 'search' feature (it's not even a 'button' most of the time) because you didn't care to use a proper <img> or <svg>

agumonkey - 2 hours ago

in early react days, and slightly before, the fun part was bidirectional binding and computed reactive values... but i admit that now it's become a big jungle just to recreate everything, plus it's rarely stable, new ui libs pop every year (shadcn is now rebasing on top of base ui i believe) .. seems wasteful now

caseyross - 5 hours ago

This is only "overcomplex" from a naive point of view.

Radio buttons, as with all UI controls, have tremendous inherent complexity, which comes to light once requirements ask for something beyond the blessed happy path of the default browser button. Pixel perfect styling, animations, focus behaviors, interactions with external state, componentized branding to fit in with companies' ecosystems, etc.

The baseline <input> paradigm struggles to provide the tools needed to adequately handle this complexity, even today, after many decades of web development.

And of course --- you can also argue that we should all just use the default browser button and everything should be solved. But this is also suboptimal, as it's clear from research that users prefer custom buttons if they provide more "features" than the defaults.

gustavorg - 4 hours ago

As I was reading this text, my hands started sweating, my head began to ache, and I felt the anguish and terror of reliving a traumatic experience all over again. I can’t even count how many times I’ve been stuck in a project that’s already behind schedule, where the client (I’m a freelancer, working directly with the person who has the requirement) throws in a ‘simple’ request like: change the style of that radio button so it matches this other one. The problem isn’t that—because of reasons like the ones explained in the article—I end up spending hours and hours on what looks like a trivial task. The real nightmare is when the client asks me: ‘Why are you taking so long to do something so dumb?’ It’s a nightmare. That’s why I ran away from React, because of this and countless similar situations, and went back to WordPress, where the world is so much simpler, the clients are happy, and so am I.

kaizenb - 4 hours ago

I use shadcn/ui for side projects, mostly coding with agents.

Good to have a base design system for building products.

Are there any alternatives? Coded systems, not just UI components.

- 5 hours ago
[deleted]
interstice - 5 hours ago

The dropdown systems are something else, I spent almost as much time on that as I did on the rest of the interface when I tried Shadcn.

feverzsj - 5 hours ago

That's why I never touch web frontend dev.

maelito - 6 hours ago

Note on the fact that this would add JS that needs to be loaded to see the page. No, because similar smart people created server-side rendering, adding another layer of complexity.

notpushkin - 2 hours ago

Shadcn is an anti-pattern.

pembrook - 5 hours ago

It has to be this way because we (the collective we) refuse to agree on adding proper UI primitives to the web.

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.

joduplessis - 5 hours ago

Yup. Unfortunately common I think - not just with UI components. Occam's razor is sometimes only for others.

eddie1o - 6 hours ago

There has to be a reason for picking button instead of input type="radio", right?

supermatt - 5 hours ago

> Why would you want to do this?

Have you tried completely customising a radio button with CSS? Feel free to demonstrate a heavily customised radio button style where you don’t hide the native appearance.

shubhamjain - 6 hours ago

This is the reason I absolutely hate shadcn. The number of dependencies and files you introduce for trivial components is insane. Even tiny little divs are their own component for no good reason. I genuinely don’t understand how front-end developers accept this level of needless complexity.

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.

[1]: https://basecoatui.com/

dzonga - 2 hours ago

we've new dev's been trained that this is normal - a.i putting out slop / trained on this cz its the default

yeah sad state of affairs

jojobas - 4 hours ago

And then you realize this paradigm plagues even desktop applications through electron and the like. Enshittification knows no borders or limits.

janlucien - 4 hours ago

[dead]

draw_down - an hour ago

[dead]

demarq - 6 hours ago

[flagged]

PunchTornado - 6 hours ago

and people complain about AI code?