Why every AI-generated website looks exactly the same.
And who's really to blame. Hint: it's not the component library.
You’ve noticed it, right? You open a link someone sent you, some new startup, a side project, a tool someone built over the weekend, and before you even read a single word, something feels… familiar. The buttons look the same. The cards have that same rounded corner. The sidebar is in the same spot. Even the little loading spinner feels like you’ve seen it before. You probably have. Like, a hundred times.
This isn’t a coincidence. And it’s not really the AI’s fault either, though it gets most of the blame. The real story is a bit more interesting then that, and it starts with something called shadcn/ui.
First, let’s talk about what’s actually happening
If you’re not a developer, here’s the deal. Building a website used to require a lot of manual work. You had to write code that controlled how every button looked, how menus behaved, how forms worked. It was tedious and slow.
Then came something called component libraries. Think of these like IKEA furniture, but for websites. Instead of building a table from scratch, you just grabbed a pre-built one, assembled it, and called it done. It looked fine, it worked, and you saved a ton of time.
For years, developers used libraries like Bootstrap or Material UI. If you used the internet in the 2010s, you seen Bootstrap sites everywhere. Same buttons, same navbars, same look. It had a phase.
Now we’re in a new phase. A different tool became hugely popular: shadcn/ui. And on top of that, AI tools like Cursor, Bolt, v0, Lovable, and others started letting people build entire apps just by typing what they wanted in plain english. No code required, technically.
The result? An absolute flood of websites, apps, and tools that all look like they came out of the same factory. Which, sort of, they did.
So what is shadcn/ui, actually?
Okay, a little more context and then we’ll get to the good stuff.
shadcn/ui is a collection of UI components built by a developer named Shadcn (his handle online). It came out around 2023 and basically took the developer world by storm. The components included things like buttons, dropdowns, dialog boxes, data tables, forms, everything you need to build a modern looking interface.
But here’s what made it genuinely different from what came before, and this part matters: shadcn/ui didn’t work like a normal library. You didn’t install it as a package and just use it. Instead, you copied the source code directly into your project. The components literally lived in your codebase. You owned them. You could do whatever you wanted with them.
This was kind of a radical idea. The whole point was that you’d use shadcn as a starting point, not a finish line. The components where unstyled enough to be flexible, built on solid primitives (a layer called Radix UI underneath), and designed to be customized, changed, rebuilt, made into something uniquely yours.
And it was genuinely good. Like, really well built. Clean code, good accessibility, smart defaults. Developers loved it. It became one of the most starred projects on GitHub almost overnight.
Then AI entered the chat
Here’s where everything starts going wrong.
Somewhere around 2024 and into 2025, AI coding tools exploded. Tools like Bolt, v0, Lovable, and Cursor made it possible for pretty much anyone to generate a functioning web app in minutes. You type “build me a SaaS dashboard for tracking invoices” and it just… does it.
These tools needed to make choices about what components and styles to use. And, well, shadcn/ui was enormously popular, very well documented, and the AI models had seen so much of it in training data that it became the default answer to almost every UI question.
So every generated app came out using shadcn. Gray cards with subtle borders. Neutral color palettes. Clean sans-serif fonts. A sidebar on the left. A data table in the middle. A button group in the top right. A toast notification that slides in from the bottom corner.
You’ve seen this app. We’ve all seen this app. It now exist in roughly ten thousand slightly different forms across the internet.
The part that’s actually frustrating
Here’s the thing that gets me. And honestly should get any developer who’s thought about this for more than five minutes.
shadcn was never supposed to be the final product.
The entire philosophy of the library was: take this, make it yours. The creator literally said this. The docs said this. The architecture said this. You own the code, so change the code. Adjust the radius on those buttons. Rip out the gray color scheme. Build your own components on top of the primitives. Use it as a foundation.
That’s literally what the tool was for.
Instead, what happened is developers, and especially AI tools, treated shadcn like a finished design system. Like, great, done, ship it. No custom colors. No adjusted spacing. No brand personality. Just the defaults, out of the box, sent straight to production.
And now the same developers and users who did this are out here complaining that shadcn makes everything look like slop. There’s actual discourse online about how shadcn is making the web ugly.
Which is… a choice of opinion, I guess. But wrong.
shadcn didn’t make your app ugly. Laziness made your app ugly. Or, more charitably, the AI tools that skipped the customization step made your app ugly.
Why did this actually happen though?
To be fair to developers, there’s real reasons this became the norm and not all of them are laziness.
First, the AI tools optimized for speed, not identity. When Bolt or v0 or Cursor generates an app, it’s goal is to produce something that works. Something that the user can look at and say “yes, that’s what I asked for.” Custom design systems and brand identities are not part of that loop. They’re invisible to the model unless you specifically ask for them, and even then, the output tends to revert to defaults.
Second, most people generating apps with AI aren’t designers. They’re developers who want to ship fast, or non-technical founders who just want something functional. Design decisions feel risky when you’re not trained to make them. Sticking with the defaults feels safe. Which it is, mostly. But safe is another word for forgettable.
Third, and this one’s important, customizing shadcn actually takes real work. You can’t just tell an AI “make this look different” and get something genuinely distinctive out the other end. Building a real design system, even on top of great primitives like Radix and shadcn, requires thought. Decisions about spacing, color theory, typography, interaction patterns. These things take time and intention.
So the rational choice for most people building fast was: use the defaults, ship the thing, move on.
The irrational part is then turning around and blaming the tool.
What shadcn actually got right (and still does)
Lost in all this discourse is the fact that shadcn/ui is, genuinely, an excellent piece of work.
The component primitives are accessible by default, which is something a lot of developers don’t even think about until someone complains. The code quality is clean and readable. The composability is great, meaning components work together naturally without a lot of fighting. And the decision to let you own the source was, and remains, ahead of its time.
There’s not many UI libraries where you can go into the button component and change literally anything about it without worrying about breaking an upstream dependency or waiting on a package update. With shadcn you just open the file and change it. That’s a real advantage that most people using it never took.
The boring, neutral aesthetic of the default shadcn components was also, arguably, a feature and not a bug. Neutral doesn’t impose. It gives you room. A very opinionated component library forces your hand. shadcn said “here’s a very good blank canvas, go paint something.”
Most people just… didn’t paint anything.
The bigger problem is how we’re building now
This shadcn situation is really just a symptom of something bigger happening in how software gets made.
We’ve entered a phase where the gap between “can build something” and “can build something good” has gotten weirdly wide again. AI tools closed the skill gap for getting something working. But they didn’t close the taste gap. They didn’t close the design thinking gap. They didn’t close the “does this thing have a soul” gap.
Every app that comes out of Bolt with its default shadcn components is technically functional. It do the thing it says it does. But it doesn’t feel like anything. It has no identity. It could be any app. It probably is.
The web used to have a lot more personality, even if that personality was sometimes terrible. Geocities sites were ugly but they was someone’s. Flash sites from the 2000s were often annoying but you remembered them. Early indie web stuff had character.
Now a huge portion of new apps and sites are basically identical. And because they’re generated so fast, there’s more of them every week.
What should actually happen
Nobody is obligated to build a highly customized design system for a side project they’re testing over a weekend. That would be ridiculous. Use the defaults, validate the idea, iterate later.
But a few things should probably change.
AI tools should be much better at asking design questions before generating UI. Not just “what do you want to build” but “what should this feel like? who is this for? what one word describes the brand?” That context changes the output dramatically.
Developers who are shipping real products, with real users, and real business goals, should treat the shadcn defaults as literally day one of the design process. Not day one hundred. Use it to get started, then do the work.
And maybe, just maybe, we should stop blaming the component library for choices the developers and the tools made. shadcn gave you source code and said do something with it. Thats a gift. A lot of people just left it unopened.
Closing thought
There’s something kind of poetic about this whole situation. A library built on the philosophy of “own your code, make it yours” became the engine behind a thousand cookie-cutter apps that look like nobody owns them at all.
shadcn/ui didn’t fail the web. The web just moved to fast to think about what it was building.
The tools are good. The primitives are solid. The foundation is there.
Someone just needs to actually build something on top of it.