78 comments

[ 2412 ms ] story [ 2016 ms ] thread
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.
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.
I still don't understand why someone would choose to essentially clone some code vs import a library. Suddenly you increase your maintenance burden, lose updates, etc. I've had no problems at all with UI libraries like Mantine. If you follow this logic, why not just clone all your npm repos and build from source. Ultimate control, right? Please help me understand the benefits here, because I tried out shadcn and wasn't into it
There has to be a reason for picking button instead of input type="radio", right?
The shadcn radio button in action: https://ui.shadcn.com/docs/components/radio-group
(comment deleted)
For some reason it's exceptionally slow for me on chromium. I click and I see it register half a second later. It also has no cursor:pointer which makes it look non-clickable. Is it expected or a bug?
Straight up doesn't even register clicks or keyboard focus for me in firefox.
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.
It needs JS to be interactive unlike the native radio button
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.

Author here.

You can do pretty much any styling!

I did a basic example because that matches what Shadcn does (black/white circle) but you can customize it a lot more.

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/

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?

photopea.com is entirely written in JavaScript and as far as I know, it doesn't use any fancy JS framework.
We went out of business, but I made a web app for videographers to collaborate during production. Same things as frame.io. This was over 15 years ago. Frontend was pretty vanilla except relied heavily on jQuery. The main section of the app allowed you to commend on specific frames in a video. The code is split up amongst multiple files. Here is one: https://github.com/StevePotter/Takeoff/blob/main/Takeoff.Web...

Look at any of the sibling `app-productions-details*.js` files. Combined they formed a single interface. It was dicey. But damn the interface was snappy. I mean, instant. Code would have been much less these days but probably nowhere near as responsive.

As company size grows, managers want to settle on a "standardized" tech stack that doesn't get in the way when they want to hire and fire people at will.

Nobody was ever fired for choosing React (or IBM). But everyone can get fired when they're working on a React app.

> Nobody was ever fired for choosing React. But everyone can get fired when they're working on a React app.

Beautifully put.

Its because everyone can see UI, and many have strong opinions on it. Its always the first tragedy of the commons. In a typical tech company built on compromise, fighting the complexity is a fools errand.
One major reason for this, in my past experience, is that designers push for heavily customised components. If you go back to them with “why not use the default radio button with a bit of styling?”, I’ve yet to work with a designer that would relent, the specs are always for crazy UI work.
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
If you're not into web development, Hacker News discussions about React are really bad way to gain unbiased perspective - it's been really popular here for last few years to just hate React (usually they know nothing, e.g. anyone who claims hooks compose worse than class components). But there's a reason why React is still used the most (large ecosystem, fast development and backwards compatibility). Of course, it's easy for inexperienced developer to produce slow and buggy apps (maybe slightly easier than in other frameworks, but that's practically unquantifiable), to include unnecessary or even badly written dependencies, etc. - but it's not the tool's fault when it's being used incorrectly.
(comment deleted)
Yup. Unfortunately common I think - not just with UI components. Occam's razor is sometimes only for others.
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.

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.

For what it’s worth, the point of React is that you can just fix that Radio component to be an input (if that makes sense) and it’ll just be an input.

React gives you boxes to put stuff into but you decide what to put into them. Then React ensures that you can change what’s in those boxes without breaking anything. That’s the power of component abstraction.

I guess it depends on your definition of complexity. Being able to think about your UI as a function of state is a lot simpler than dealing with mutability, coordinating imperative updates all over the place, etc. React’s core idea is simpler than the paradigms it replaced. By simple, I mean as in “Simple Made Easy”[0].

[0] https://m.youtube.com/watch?v=SxdOUGdseq4&pp=ygUQc2ltcGxlIG1...

> React is much more complex than the technology it's building on. Necessarily, to enable it's features

React, just like most software today, is excessively complex for the tasks it performs.

The only reason React is used is that many use it as a framework to attempt to provide more interactivity on the page without page reloads. There are other frameworks to do this, but none are as well-used.

Webpage interactivity with data was accomplished with page reloads via cgi-bin in the 1990s. Everything that has been done since then was not strictly necessary to produce the websites we use today; it would just be a more choppy experience.

A smoother experience didn’t require the overwhelming complexity that was introduced primarily in the 2010s in a framework war that React basically won. That complexity is the reason why many web and full-stack developers in the 2010s (such as myself) lost their minds and quit or seem incredibly depressed, grumpy, and confused much of the time today, and why some have invented strange new frameworks to attempt to reduce this complexity.

React was built to satisfy the specific scaling and complexity needs of Facebook, and this CV-driven industry jumped on board with it pretending that what's good for Facebook is good for them. The incentives are completely misaligned: it's like nobody gains anything out of using the least amount of force and abstraction to solve a specific problem.
I've seen React components where div is used with click event for adding a normal link
FWIW I've been writing UIs using plain JavaScript and the DOM API for like 15 years and at a certain scale, I always ended up building an ad-hoc framework or being disgruntled when I had to reach for any of the pre-React UI frameworks whose APIs and approaches I didn't like. React changes this, nowadays I either start with pure DOM and then rewrite to React or just start with React. I see a lot of hate online for React these days and I agree with probably 99 % of it, but the problem in my eyes is not React itself, but the ecosystem that spurred around it. If you stick to just React and take some care with your craft, React is a joy to use IME.
(comment deleted)
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..

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

I almost had the same reaction tbh! Like I remember inline-grid and place-content for example was not at all supported css, it would've been a nightmare to do, but modern browsers css support is way more powerful than my mental model of them still is. So it's time to update that mental model.
Yes, several times. I've been specializing in front-end dev for over a decade.

I shared a simple example because Shadcn has a simple design.

You do often hide the native appearance if you need something complex, but doing that via CSS is still much simpler than a bunch of JS and a third party dependency.

If you have a specific design in mind I can show you how to do it.

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.
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.
That's why I never touch web frontend dev.
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.

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.

Author here. I've implemented all of these with the native radio button and CSS:

> Pixel perfect styling, animations, focus behaviors, interactions with external state, componentized branding to fit in with companies' ecosystems, etc.

Do you have a more specific example of something you've struggled with recently?