웹 컴포넌트 2025년 현황
프레임워크 없이 쓸 수 있다는 웹 컴포넌트, 2025년에 실제로 쓸 만한 수준인지 직접 써봤다
매년 "올해는 웹 컴포넌트의 해"라고 하는데
솔직히 웹 컴포넌트에 대한 기대는 2018년부터 있었다. "프레임워크 없이 재사용 가능한 컴포넌트를 만들 수 있다", "표준 기술이니까 안 사라진다", "프레임워크에 종속되지 않는다." 매년 이런 말이 나오는데, 매년 React가 이기고 있었다.
근데 2025년에는 좀 달라진 것 같아서 직접 써봤다.
Custom Elements + Shadow DOM, 어디까지 왔나
버튼 컴포넌트 하나를 웹 컴포넌트로 만들어봤다. customElements.define으로 등록하고, Shadow DOM으로 스타일을 격리하고, 슬롯으로 콘텐츠를 받는 구조.
코드 자체는 깔끔했다. 근데 React로 같은 걸 만들면 절반 분량이다. 보일러플레이트가 아직 많다. connectedCallback, disconnectedCallback, attributeChangedCallback... 라이프사이클 메서드를 수동으로 관리해야 한다. React의 useEffect가 왜 편한지 다시 깨달았다.
Lit이 게임 체인저인가
구글이 만든 Lit이라는 라이브러리가 있다. 웹 컴포넌트를 쉽게 만들 수 있게 해주는 래퍼. 이걸 쓰면 보일러플레이트가 확 줄어든다. 리액티브 프로퍼티도 지원하고, 템플릿 리터럴로 HTML을 쓸 수 있다.
2주 동안 Lit으로 디자인 시스템의 기본 컴포넌트 8개를 만들어봤다. 버튼, 카드, 모달, 인풋, 드롭다운, 탭, 토스트, 아코디언. 작업 시간은 하루 평균 3시간. 총 42시간.
같은 걸 React로 만들면? 경험상 30시간 정도. 12시간 차이. 웹 컴포넌트가 아직 생산성에서는 뒤처진다. (근데 이 12시간 차이가 점점 줄어들고 있는 느낌이다.)
근데 왜 지금 다시 주목하는 건가
마이크로 프론트엔드 때문이다. 팀마다 다른 프레임워크를 쓰는 환경에서 공통 컴포넌트를 공유하려면 웹 컴포넌트가 거의 유일한 선택지다. React 팀, Vue 팀, Svelte 팀이 모두 같은 버튼 컴포넌트를 쓸 수 있다.
우리 회사에서도 이 시나리오가 현실이 됐다. 프론트 팀이 React를 쓰는데, 인사팀이 도입한 사내 도구가 Vue 기반이다. 두 시스템에서 동일한 디자인 시스템을 적용하려면? 웹 컴포넌트.
여전히 아쉬운 점들
SSR이 약하다. Declarative Shadow DOM이 나오긴 했는데, Next.js나 Nuxt에서 웹 컴포넌트를 서버 사이드 렌더링하는 건 아직 험난하다. hydration 이슈가 있다.
폼 연동도 불편하다. <form> 안에서 커스텀 엘리먼트가 기본 폼 요소처럼 동작하게 하려면 ElementInternals API를 써야 하는데, 이게 직관적이지 않다.
테스팅 도구도 React Testing Library 수준에 못 미친다. @open-wc/testing이 있긴 한데 생태계가 얇다.
결론이라기보다는 현재 위치
웹 컴포넌트는 "React를 대체할 것인가"의 프레임으로 보면 안 된다. "프레임워크와 공존하면서 교차 지점을 담당할 것인가"로 보는 게 맞다. 디자인 시스템, 마이크로 프론트엔드, CMS 위젯 같은 영역에서는 이미 실용적이다.
그냥 새 프로젝트를 시작한다면? 아직은 React 쓸 거다. 근데 공통 컴포넌트 라이브러리를 만든다면? 웹 컴포넌트를 심각하게 고려할 거다.