MDN이 React를 버린 이유 — 콘텐츠 사이트에서 Web Components가 맞는 선택인 이유

8 min read
Web ComponentsMDNReact프론트엔드성능
MDN이 React를 버린 이유 — 콘텐츠 사이트에서 Web Components가 맞는 선택인 이유

MDN이 React를 내려놨다

MDN Web Docs가 프론트엔드 스택을 전면 교체했다. React를 걷어내고 Web Components와 자체 서버 컴포넌트 시스템으로 다시 만들었다. 뉴스가 공개되자 프론트엔드 커뮤니티가 술렁였다. "굳이 왜?"라는 반응이 많았지만, 이유를 뜯어보면 꽤 합리적인 판단이다.

MDN은 콘텐츠 중심 사이트다. 대부분의 페이지는 문서고, 인터랙티브한 요소는 코드 에디터와 데모 정도다. "모든 페이지에 불필요한 JavaScript를 배포하지 않으면서 현대적인 웹사이트를 구축"하는 것이 이번 재구축의 핵심 목표였다. React가 그 목표에 맞지 않았다.


React가 콘텐츠 사이트에서 과한 이유

React는 복잡한 상태 관리와 인터랙션이 많은 앱을 위해 설계됐다. 그 대가로 런타임 JavaScript를 항상 함께 배포해야 한다. 정적 콘텐츠 페이지도 예외가 없다.

방식정적 페이지 JS 비용상태 관리인터랙션
React (기존)런타임 번들 항상 포함강력하지만 과함유연
Web Components (신규)필요한 컴포넌트만 로드가벼운 Shadow DOM충분

비유하면 문서를 공유하려고 Figma 전체를 설치하라고 요구하는 것과 같다. PDF 하나면 충분한데.

[💡 잠깐! 이 용어는?] Web Components: HTML, CSS, JavaScript를 캡슐화하는 웹 표준. Custom Elements, Shadow DOM, HTML Templates의 세 기술로 구성된다. 프레임워크 없이 재사용 가능한 컴포넌트를 만들 수 있고, 브라우저가 네이티브로 지원한다.


자체 서버 컴포넌트 시스템

MDN이 단순히 Web Components로 전환한 게 아니다. 자체 서버 컴포넌트 시스템도 함께 만들었다.

React Server Components에서 아이디어를 가져왔지만, 외부 프레임워크에 의존하지 않는다. 서버에서 HTML을 생성하고, 인터랙션이 필요한 부분만 클라이언트 Web Component로 처리한다. 불필요한 JavaScript는 브라우저에 내려가지 않는다.

컴포넌트 처리 흐름

요청
  → 서버: HTML 렌더링 (서버 컴포넌트)
  → 클라이언트: HTML 수신, 즉시 표시
  → 인터랙티브 요소만: Web Component 하이드레이션

[💡 잠깐! 이 용어는?] 하이드레이션(Hydration): 서버에서 생성된 HTML에 JavaScript 이벤트 핸들러를 붙여 인터랙티브하게 만드는 과정. React는 전체 페이지를 하이드레이션하지만, MDN의 새 방식은 필요한 컴포넌트만 선택적으로 하이드레이션한다.


Web Components의 실제 사용 패턴

MDN에서 코드 에디터나 실행 가능한 예제 같은 인터랙티브 요소는 Web Component로 구현된다.

mdn-interactive-example.html
<interactive-example id="css-animation-demo">
  <template shadowrootmode="open">
    <style>
      :host { display: block; }
      .preview { border: 1px solid #ccc; padding: 1rem; }
    </style>
    <div class="preview">
      <slot></slot>
    </div>
  </template>
  <div class="example-code">
    <!-- 예제 콘텐츠 -->
  </div>
</interactive-example>
components/interactive-example.js
class InteractiveExample extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: 'open' })
    // 컴포넌트 초기화 로직
    this.setupEditor()
    this.setupPreview()
  }
 
  setupEditor() {
    const editor = this.shadowRoot.querySelector('.editor')
    editor?.addEventListener('input', () => this.updatePreview())
  }
 
  updatePreview() {
    const preview = this.shadowRoot.querySelector('.preview')
    // 실시간 미리보기 업데이트
  }
}
 
customElements.define('interactive-example', InteractiveExample)

Shadow DOM이 스타일 캡슐화를 담당하므로 CSS 충돌 걱정이 없다. 그리고 이 JavaScript는 <interactive-example> 태그가 실제로 페이지에 있을 때만 로드된다.

[💡 잠깐! 이 용어는?] Shadow DOM: Web Components의 핵심 기술 중 하나. 컴포넌트 내부의 HTML/CSS를 외부 문서와 격리한다. 외부 CSS가 침범하지 못하고, 내부 CSS도 밖으로 새지 않는다.


이 결정이 의미하는 것

MDN이 React를 버린 건 React가 나쁜 도구라는 뜻이 아니다. 콘텐츠 중심 사이트에 맞지 않는 도구였다는 뜻이다.

사이트 유형적합한 접근
콘텐츠 중심 (문서, 블로그, 뉴스)Web Components + 서버 렌더링
앱 중심 (대시보드, SaaS, 복잡한 상호작용)React, Vue, Angular
혼합형하이브리드 (Next.js App Router 등)

"React를 쓰면 현대적인 웹 개발"이라는 등식이 흔들리고 있다. Web Components는 2011년부터 표준화가 시작됐지만 브라우저 지원과 DX가 부족해서 외면받았다. 지금은 다르다. 모든 주요 브라우저가 지원하고, Shadow DOM과 Declarative Shadow DOM이 안정화됐다.


React 없이 컴포넌트가 가능한가

흔히 하는 오해는 "컴포넌트 기반 개발 = React"라는 생각이다. Web Components는 표준이다. 프레임워크가 아니라 브라우저에 내장된 기능이다. 2026년 기준으로 전 세계 브라우저의 96% 이상이 지원한다.

단점도 있다. 상태 관리가 복잡해지면 React만큼 편리하지 않다. 생태계가 아직 React만큼 두텁지 않다. 하지만 MDN처럼 "콘텐츠가 주인이고, JavaScript는 보조"인 사이트에서는 Web Components가 더 맞는 선택일 수 있다.


마무리

MDN의 전환은 단순한 기술 선택의 변화가 아니다. "이 사이트에 진짜 필요한 게 뭔가"라는 질문에서 출발한 결과다. 불필요한 JavaScript를 싣지 않겠다는 원칙이 기술 스택을 결정했다.

  • 콘텐츠 사이트에서 JavaScript 번들을 줄이고 싶다면 → Web Components가 선택지가 된다
  • 복잡한 상태와 인터랙션이 필요하다면 → React/Vue의 이유는 여전히 충분하다

중요한 건 도구를 고르는 기준이다. "모두가 쓰니까"가 아니라 "이 문제에 맞는 도구인가"로 판단하는 것. MDN이 보여준 게 바로 그것이다.


참고:

관심 있을 만한 포스트

React Compiler의 한계 — 뭘 최적화하고 뭘 못 하는가

React Compiler가 자동 메모이제이션으로 해결하는 것과 해결하지 못하는 것. 컴파일러 기반 UI 프레임워크의 능력 경계를 정리했다.

ReactReact Compiler

Zustand 소프트 삭제 — enumerable:false로 컴포넌트 크래시 없이 처리하기

JavaScript property descriptor의 enumerable 플래그를 활용해 삭제된 엔티티를 투명하게 처리하는 Zustand 패턴을 소개한다.

Zustand상태 관리

SVG 아이콘 — 코드 배포 없이 프로덕트 팀이 직접 관리하는 법

CSS mask-image와 S3를 조합해 개발자 개입 없이 아이콘을 교체하는 패턴을 소개한다.

SVGCSS

HTML Minifier 벤치마크 — 48개 사이트에서 어떤 도구가 이겼나

minify-html, htmlnano, HTML Minifier Next, @swc/html 등 주요 HTML 압축 도구를 실제 사이트로 비교한 벤치마크 결과와 선택 기준을 정리한다.

HTMLMinifier

JavaScript 이미지 프리로딩 — 5가지 방법 비교

new Image, link preload, hidden div, Cache API, fetch — 각 프리로딩 방식의 장단점과 상황별 선택 기준을 정리한다.

JavaScript성능

React 상태 올리기 — 대부분의 경우 하지 않는 게 낫다

React에서 습관적으로 lift state up을 하는 안티패턴을 살펴보고, 상태를 쓰는 곳 가까이 두는 편이 왜 더 나은지 정리한다.

React상태 관리

CSS 한 줄로 업그레이드 — 지금 바로 적용할 수 있는 12가지 모던 CSS 속성

aspect-ratio부터 scrollbar-gutter까지, 한 줄 추가로 스타일시트를 현대화하는 12가지 CSS 속성을 정리한다.

CSS모던 CSS

Angular 1에서 React로 — Strangler 패턴으로 1년간 점진적 마이그레이션한 이야기

대규모 티켓 플랫폼을 Angular 1에서 React로 마이그레이션하면서 적용한 Strangler 패턴과 7가지 교훈을 정리한다.

ReactAngular