# Shadcn 라디오 버튼의 과도한 복잡성

> Clean Markdown view of GeekNews topic #25998. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25998](https://news.hada.io/topic?id=25998)
- GeekNews Markdown: [https://news.hada.io/topic/25998.md](https://news.hada.io/topic/25998.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-01-21T09:46:12+09:00
- Updated: 2026-01-21T09:46:12+09:00
- Original source: [paulmakeswebsites.com](https://paulmakeswebsites.com/writing/shadcn-radio-button/)
- Points: 2
- Comments: 4

## Topic Body

- 웹 브라우저에 기본 내장된 **라디오 버튼**이 단순한 HTML 요소임에도, Shadcn UI 라이브러리에서는 이를 여러 계층의 React 컴포넌트로 재구성함  
- Shadcn의 `&lt;RadioGroup&gt;`과 `&lt;RadioGroupItem&gt;`은 **Radix UI**의 컴포넌트를 다시 감싸며, **lucide-react 아이콘**과 **수십 개의 Tailwind 클래스**를 사용  
- Radix는 접근성과 커스터마이징을 위해 **ARIA 속성**을 활용하지만, 실제로는 기본 `&lt;input type="radio"&gt;` 대신 버튼 요소를 재활용함  
- 단순한 CSS로도 동일한 스타일링이 가능함에도, 이 구조는 **수백 줄의 코드와 여러 종속성**을 추가해 불필요한 복잡성을 초래  
- 기본 HTML 요소를 재사용하지 않음으로써 **성능 저하와 유지보수 부담**이 커지고, 웹 개발의 단순함이 훼손됨  

---

### Shadcn 라디오 버튼 구조 분석
- Shadcn은 `&lt;RadioGroup&gt;`과 `&lt;RadioGroupItem&gt;` 두 컴포넌트를 통해 라디오 버튼을 구현  
  - 각 컴포넌트는 `@radix-ui/react-radio-group`에서 가져온 프리미티브를 감싸며, `lucide-react`의 **CircleIcon**을 사용  
  - 45줄 이상의 코드와 3개의 외부 import가 포함되어 있으며, **30개 이상의 Tailwind 클래스**로 스타일 지정  
- 단순한 원형 표시를 위해 **SVG 아이콘 라이브러리**를 불러오는 구조  
  - CSS의 `border-radius`나 `&lt;circle&gt;` 요소로 대체 가능한 기능임  

### Radix UI의 역할
- Shadcn이 사용하는 Radix는 **접근성과 커스터마이징 중심의 저수준 UI 컴포넌트 라이브러리**  
  - Radix의 라디오 그룹 구현은 약 **215줄의 React 코드**와 7개의 파일을 import  
- Radix는 `&lt;button&gt;` 요소에 **ARIA 속성**을 추가해 라디오 버튼처럼 동작하도록 구성  
  - 그러나 **W3C의 ARIA 사용 제1원칙**은 “가능한 경우 기본 HTML 요소를 사용할 것”으로 명시  
  - Radix는 이 원칙을 따르지 않고, `&lt;input&gt;` 대신 버튼을 재활용함  
- `&lt;form&gt;` 내부에서만 숨겨진 `&lt;input type="radio"&gt;`를 추가하는 구조로, 일관성이 떨어짐  

### CSS로 가능한 단순한 대안
- 기본 HTML 라디오 버튼은 `appearance: none`, `::before`, `:checked`, `border-radius` 등으로 손쉽게 스타일링 가능  
  - 예시 코드에서는 **의존성, 자바스크립트, ARIA 속성 없이** 완전한 커스터마이징 구현  
  - 동일한 효과를 Tailwind로도 구현 가능  
- “라디오 버튼 스타일링은 어렵다”는 인식은 과거의 문제이며, 현재는 **순수 CSS만으로 충분한 제어 가능**  

### 복잡성의 누적 문제
- Shadcn과 Radix를 함께 사용하면 **두 개의 라이브러리와 수백 줄의 코드**를 이해해야 함  
  - 단순한 라디오 버튼 하나를 위해 **수 KB의 자바스크립트**가 추가 로드됨  
  - 사용자는 버튼 토글을 위해 JS 파싱과 실행을 기다려야 함  
- 이러한 구조는 **인지 부하 증가**, **버그 가능성 확대**, **웹 성능 저하**로 이어짐  

### 단순함으로의 회귀
- 브라우저는 이미 라디오 버튼을 기본 제공하며, `&lt;input type="radio" name="beverage" value="coffee" /&gt;` 한 줄로 충분  
- 불필요한 추상화와 중첩된 라이브러리 사용은 **웹 개발의 본래 단순성과 효율성**을 해침  
- 작은 UI 요소라도 **기본 기능을 재활용하는 설계**가 유지보수성과 성능 모두에 유리함

## Comments



### Comment 49607

- Author: crawler
- Created: 2026-01-21T12:59:00+09:00
- Points: 2

지루하고 현학적:  
```js  
function RadioGroup({  
  className,  
  ...props  
}: React.ComponentProps&lt;typeof RadioGroupPrimitive.Root&gt;) {  
  return (  
    <RadioGroupPrimitive.Root  
      data-slot="radio-group"  
      className={cn("grid gap-3", className)}  
      {...props}  
    />  
  );  
}  
...  
```  
  
금방 끝남 오래 기억에 남음:   
```html  
&lt;input type="radio" name="beverage" value="coffee" /&gt;  
```

### Comment 49653

- Author: slowandsnow
- Created: 2026-01-22T07:17:07+09:00
- Points: 1

react aria의 버튼 컴포넌트 보면 기절할 듯 ㅋㅋ

### Comment 49630

- Author: preserde
- Created: 2026-01-21T17:50:21+09:00
- Points: 1

제가 frontend 분야라 오랫동안 겪은 문제인데, 뭐랄까 해결이 정말 어려운 문제이긴 합니다. 구현은 시대에 따라 계속 바뀌고 있지만 input type으로 해결하지 않는 건 어느 시대나 똑같네요...  
웹브라우저의 라디오 체크박스 버튼 동작 흉내내보겠다고 접근성 관련 스펙을  따로 구현하는 건 대체 뭐하자는건지... 모르겠어요... 본문에 있듯 css로도 지금은 대안이 있는데 죽어도 컴포넌트로 구현하겠다고 하는 걸 보면 좀 웃기긴 합니다.

### Comment 49578

- Author: neo
- Created: 2026-01-21T09:46:12+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46688971) 
- 프론트엔드를 자주 다루지는 않지만, **React**가 주류가 되던 시점부터 복잡성이 커질 조짐이 보였음  
  다른 추상화 계층은 단순화되는 경향이 있지만, React는 그 기반 기술보다 훨씬 **복잡한 추상화**를 만들어냄  
  React만 아는 개발자들이 점점 더 높은 레이어로 쌓아 올리면서 과도하게 설계된 결과를 낳는다고 느낌
  - 이제는 모두가 React가 기본값이라고 **당연히 여기는 분위기**가 더 문제라고 생각함  
    예를 들어 [Shadcn](https://ui.shadcn.com)이나 [Radix](https://www.radix-ui.com)는 React 전용 UI 라이브러리인데, 마케팅 문구만 보면 일반적인 UI 라이브러리처럼 보임
  - 나는 15년 넘게 순수 **JavaScript와 DOM API**로 UI를 만들어왔음  
    규모가 커지면 결국 나만의 프레임워크를 만들거나 기존 프레임워크에 불만을 품게 됐는데, React는 그 문제를 어느 정도 해결해줌  
    React 자체보다 **생태계의 과잉 복잡성**이 문제라고 봄. React만 잘 다루면 여전히 즐겁게 쓸 수 있음
  - 이건 React만의 문제가 아니라, 사람들이 **현대 CSS**를 배우려 하지 않는 게 더 큰 문제라고 생각함  
    Tailwind 같은 도구로 CSS를 우회하려고만 함. 나는 React로 상태를 관리하지만, 스타일링은 CSS로 직접 하는 걸 선호함  
    팀원들에게 CSS를 배우게 설득하는 게 가장 어려운 일임
  - 추상화는 본래 **복잡성을 감추는 철학적 도구**여야 하는데, 요즘은 오히려 더 복잡하게 만드는 경우가 많음  
    나는 이런 “현대적” 프레임워크를 피하고, 가능한 한 **기본 기술**을 선호함
  - React의 핵심은 **컴포넌트 추상화**임  
    React는 단지 “박스”를 제공하고, 그 안에 무엇을 넣을지는 개발자가 결정함. 그게 React의 진짜 힘임

- 이 라디오 버튼 예시는 웃기면서도 인상적임  
  결과물은 기본 CSS 라디오 버튼과 구분이 안 되는데, 왜 이렇게 복잡하게 만드는지 의문임  
  큰 규모의 사이트 중 이런 **불필요한 복잡성 없이** 만들어진 사례가 있는지 궁금함
  - [McMaster-Carr](https://www.mcmaster.com) 사이트가 좋은 예시로 자주 언급됨. 관련 [Hacker News 스레드](https://news.ycombinator.com/item?id=32976978)도 있음
  - 15년 전 비디오 협업 웹앱을 만들었는데, 프론트엔드는 거의 **jQuery 기반의 바닐라 구조**였음  
    지금보다 코드량은 많았지만, 인터페이스는 **즉각 반응하는 속도감**이 있었음  
    [Takeoff 프로젝트 코드](https://github.com/StevePotter/Takeoff/blob/main/Takeoff.WebApp/scripts/app-productions-details-videodetails.js) 참고 가능
  - “이 사이트는 어때?” — 바로 이 **Hacker News 자체**가 그런 예시일지도 모름
  - 회사 규모가 커질수록 관리자는 **표준화된 스택**을 원함  
    “React를 선택해서 잘린 사람은 없다”는 말처럼, 안전한 선택이 되어버림
  - UI는 모두가 볼 수 있고 의견이 많기 때문에, **복잡성이 공공재의 비극**처럼 커지는 구조임

- 개발자는 디자인 요구사항에 **항상 반박할 수 있음**을 기억해야 함  
  React Native에서 단순한 레이아웃 문제로 4시간을 낭비하던 개발자에게 “디자인을 조금 바꿔도 되냐”고 물어보라 했더니, 10분 만에 해결됨  
  - 나는 요즘 **JS 없는 UI 프레임워크**들(Pico.CSS, Skeleton, Bulma, Tailwind/daisyUI)을 선호함  
    CSS만 잘 써도 충분히 좋은 결과를 얻을 수 있음. 혹시 이런 접근 써본 사람들의 추천이 궁금함

- 2025년에 가장 큰 실수는 **Shadcn**을 선택한 것이었음  
  Radix를 계속 import하는 걸 보고 첫 번째 경고, radio 컴포넌트를 보고 두 번째 경고를 느낌  
  이미 프로젝트가 진행 중이라 포기하고 Copilot으로 수정했지만, 결과적으로 **AI 의존**도 마음에 들지 않았음  
  이전 POC는 훨씬 단순하고 효율적이었음. 언젠가 전부 **바닐라 HTML로 다시 만들고 싶음**
  - React+NextJS+Tailwind+Shadcn 조합은 **복잡함의 끝판왕**임  
    Remix나 React Router 7은 그래도 웹 표준에 가깝게 유지하려는 시도가 있었음  
    Tailwind에서 “이건 아니다” 싶었고, 친구들이 리팩터링 후에도 좋다고 하면 그때 다시 볼 생각임
  - 사실 Tailwind와 React는 잘 맞지 않음  
    React에는 **props 기반의 스타일링**이 있는데 굳이 CSS 클래스 덩어리를 쓸 이유가 없음  
    접근성 중심이라면 Radix UI만 써도 충분함

- 브라우저의 `&lt;input&gt;` 요소, 특히 **radio와 select**는 커스터마이징이 어렵다는 게 문제임  
  기본 라디오 버튼은 모바일에서 **사용성이 떨어짐**
  - 사실 네이티브 컨트롤도 CSS로 충분히 스타일링 가능함  
    모바일에서 어떤 문제가 있었는지 더 구체적으로 알고 싶음
  - 글에서도 CSS로 라디오 버튼을 꾸미는 방법을 설명함. 그게 문제인가?
  - `&lt;label&gt;`로 감싸고 패딩을 주면 모바일에서도 충분히 쓸 만함
  - “select”만큼은 여전히 스타일링이 까다롭지만, 나머지는 꽤 유연하게 커스터마이징 가능함

- 대부분의 프로젝트는 좋은 의도로 시작하지만, 어느새 **200줄짜리 라디오 버튼 코드**와 7개의 import로 가득 차게 됨  
  이렇게 **코드 부패(code rot)** 가 시작됨

- 최근 [daisyUI](https://daisyui.com/)를 써봤는데 꽤 마음에 듦  
  순수 CSS 기반이라 브라우저의 **새로운 기능(dialog 등)** 을 잘 활용할 수 있음
  - 하지만 접근성 측면에서는 부족함이 많음  
    예를 들어 [Drawer](https://daisyui.com/components/drawer/)는 포커스를 가두지 못하고, [Accordion](https://daisyui.com/components/accordion/)은 라디오 버튼을 **JS 대체용으로 남용**함  
    이런 이유로 Radix 같은 라이브러리가 복잡해질 수밖에 없음

- 글의 요지에는 공감하지만, 디자이너가 Figma에서 만든 **정확한 스타일을 모든 브라우저에서 동일하게 구현**하려면 바닐라 CSS로 가능한지 궁금함  
  [Radix의 데모](https://www.radix-ui.com/primitives/docs/components/radio-group) 같은 걸 완전히 재현할 수 있을까?
  - 약간의 수정만으로도 꽤 비슷하게 만들 수 있음  
    [CodePen 예시](https://codepen.io/erikaja/pen/RNRVMyB) 참고 가능
  - 결국 그 복잡한 프레임워크 아래에서도 **CSS가 핵심**임  
    CSS만 추출해서 간단한 React 컴포넌트에 붙이면 충분함
  - [이 예시](https://codepen.io/mcintyre94/pen/pvbPVrP)처럼 바닐라 input과 동일한 CSS를 적용하면 브라우저 호환성도 좋음
  - 글쓴이 본인이 직접 등장해, “기본 예시를 단순히 Shadcn 스타일에 맞춘 것일 뿐, **원하면 얼마든지 커스터마이징 가능**하다”고 밝힘
  - 하지만 어디까지 완벽함을 추구할지 고민됨  
    약간의 시각적 불일치를 피하려고 **수십 KB의 코드와 유지보수 부담**을 추가하는 게 과연 가치 있는가?  
    남춘백(백남준)의 말처럼 “너무 완벽하면 신이 화낸다”는 생각이 듦

- 진짜 비용은 코드가 아니라 **온보딩 시간**임  
  새로 합류한 개발자가 Radix 기반의 47줄짜리 라디오 버튼을 이해하려면 몇 주가 걸림  
  반면 바닐라 방식은 하루면 만들고 20분이면 설명 가능함  
  물론 Figma나 Linear처럼 **접근성과 키보드 내비게이션**이 중요한 제품이라면 복잡성이 정당화됨
  - 좋은 라이브러리는 내부 구조를 몰라도 쓸 수 있게 해야 하지 않을까 하는 의문이 있음

- 많은 댓글이 Shadcn을 비판하지만, 나는 오히려 **컴포넌트 구조와 재사용성**을 잘 장려한다고 생각함  
  Shadcn의 핵심은 “컴포넌트를 직접 소유하고 수정하라”는 철학임  
  이는 기존 UI 라이브러리와는 **근본적으로 다른 접근**임
