Sitemap
Harjot Singh Rana

Harjot Singh Rana

22, engineer, always building something cool

shadcn/ui alternatives for React components that survive edge cases

4 min readOct 17, 2026

--

Note: I wrote this with AI help and then edited it myself. The test cases are real ones from the Brio UI repo.

I like shadcn/ui. It gives you buttons, dialogs, tabs and selects as source files you own, and that model changed how a lot of us build React apps. I build Brio UI on the same idea: you copy one file into your project and it’s yours.

The gap shows up one level higher. A pricing section, an FAQ with search, a one-time code input. These are the parts you build on top of the primitives, and they are where my bugs used to live. Prices in yen overflow the card. A German compound word pushes the FAQ off a phone screen. Someone pastes a six-digit code into the second box.

This post is about what to use next to shadcn/ui when those composed parts keep breaking.

What shadcn/ui gives you, and what it leaves to you

shadcn/ui is a set of primitives with good defaults. You run the CLI, the file lands in components/ui, and you style it from there. That's the right call for a button. It's a lot of work for a pricing table, because the pricing table is where the real-world data comes in: currencies, long plan names, locales that group digits differently, people who drag the toggle halfway and let go.

Nobody ships a primitive that handles your pricing copy. You end up writing that layer yourself, every project.

The test I use: the worst case, not the demo

Before I call a component done, I give it two fixtures. One is the nice demo data. The other is the worst thing I can think of. This is a method I took from Emil Kowalski: design for the ugly input first, and the pretty one takes care of itself.

Get Harjot Singh Rana’s stories in your inbox

Join Medium for free to get updates from this writer.

For the Pricing Toggle, the worst case includes:

  • a plan called “Enterprise Unlimited Plus (annual commitment, invoiced, minimum 250 seats)”
  • a price of 9,999,999 per month
  • a negative price (a credit)
  • a plan where yearly costs more than monthly
  • sub-cent API pricing in Kuwaiti dinar with 3 decimals
  • yen, Arabic-Indic digits, Devanagari digits and Indian lakh grouping

Then I screenshot it at 320 pixels wide and keep that screenshot as a visual baseline, so a later change can’t quietly break it.

Pricing Toggle worst case at 320px: very long plan names, huge and negative prices, mixed currencies

The FAQ gets the same treatment: 120 questions with 4 open on load, a 200-character question with a 79-character German compound, an unbroken 130-character URL, questions in Japanese, Arabic, Chinese and Hindi, a right-to-left instance, and a javascript: link that has to stay hidden.

FAQ worst case at 320px: long questions, a German compound word and an unbroken URL

Where else to look

If you need more than shadcn/ui, these are the places I’d check, depending on the job:

  • Radix UI or Base UI if you want unstyled, accessible primitives and plan to do all the styling yourself.
  • Origin UI (now at coss.com/origin) if you want a big collection of copy-and-paste app UI components built with Tailwind CSS and React.
  • Magic UI or Aceternity UI if you want components and templates for a landing page.
  • Brio UI if you want the everyday composed parts (pricing toggle, FAQ, code input, contact form) with the edge cases already tested.

They mix fine. Brio components only depend on React and Motion, so they sit next to shadcn/ui in the same project without fighting it.

What a Brio component looks like

Each component is a single file. Here’s the Pricing Toggle: drag the switch halfway and every price sits halfway between monthly and yearly, then it snaps when you let go.

Press enter or click to view image in full size
Brio UI Pricing Toggle with three plans and a monthly/yearly switch

Install it with the Brio CLI:

npx brio-ui add pricing-toggle

or with the shadcn CLI, if that’s what your project already uses:

npx shadcn@latest add https://brioui.com/r/pricing-toggle.json

Usage is small:

import { Billing, BillingPrice, BillingSwitch } from '@/components/brio/pricing-toggle'

export function ProPlan() {
return (
<Billing>
<BillingSwitch />
<BillingPrice monthly={12} yearly={9.6} suffix="/mo" />
</Billing>
)
}

Every component supports light and dark themes and respects reduced motion. The free ones are MIT licensed.

Which one should you pick

Keep shadcn/ui for primitives. When you notice you’re writing the same pricing, FAQ or code input logic for the third time, and fixing the same overflow bug for the third time, that layer is worth replacing with something that has already been tested against bad data.

The free Brio components are at brioui.com. Try the worst-case data from your own app on them and tell me what breaks.

--

--

Harjot Singh Rana
Harjot Singh Rana

22, engineer, always building something cool