React Compiler v1.0

TMT

React 팀은 새로운 업데이트를 공유하게 되어 기쁩니다:

  1. React Compiler 1.0이 오늘부터 사용 가능합니다.
  2. 컴파일러 기반 린트 규칙이 eslint-plugin-react-hooksrecommendedrecommended-latest 프리셋에 포함되어 배포됩니다.
  3. 점진적 도입 가이드를 공개했으며, Expo, Vite, Next.js와 협력하여 새로운 앱이 컴파일러를 활성화한 상태로 시작할 수 있게 했습니다.

오늘 컴파일러의 첫 번째 안정 버전을 릴리스합니다. React Compiler는 React와 React Native 모두에서 작동하며, 리라이팅 없이 컴포넌트와 훅을 자동으로 최적화합니다. 이 컴파일러는 Meta의 주요 앱들에서 실전 테스트를 거쳤으며, 완전히 프로덕션 준비가 되어 있습니다.

React Compiler는 자동 메모이제이션을 통해 React 앱을 최적화하는 빌드 타임 도구입니다. 작년에 React Compiler의 첫 베타를 공개했고, 많은 훌륭한 피드백과 기여를 받았습니다. 컴파일러를 도입한 분들이 얻은 성과에 대해 매우 고무적이며(사례: Sanity Studio, Wakelet), React 커뮤니티의 더 많은 사용자에게 컴파일러를 제공하게 되어 기대가 큽니다.

이번 릴리스는 거의 10년에 걸친 방대한 복잡한 엔지니어링 노력의 결실입니다. React 팀의 최초 컴파일러 탐색은 2017년 Prepack에서 시작되었습니다. 이 프로젝트는 결국 종료되었지만, 향후 컴파일러를 염두에 둔 Hooks 설계에 많은 교훈을 제공했습니다. 2021년에는 Xuan Huang이 새로운 접근의 첫 번째 이터레이션 을 데모했습니다.

새로운 React Compiler의 첫 버전은 결국 다시 작성되었지만, 초기 프로토타입은 이 문제가 해결 가능한 것이라는 확신을 높여 주었고, 대체 컴파일러 아키텍처의 학습을 통해 우리가 원하는 메모이제이션 특성을 정확히 제공할 수 있다는 것을 보여주었습니다. Joe Savona, Sathya Gunasekaran, Mofei Zhang, Lauren Tan은 컴파일러 아키텍처를 제어 흐름 그래프(CFG) 기반의 고수준 중간 표현(HIR)으로 옮기는 첫 리라이트를 진행했습니다. 이는 훨씬 더 정교한 분석과 심지어 React Compiler 내의 타입 추론까지 가능하게 했습니다. 그 이후로 컴파일러의 많은 중요한 부분이 다시 작성되었으며, 각 리라이트는 이전 시도에서 얻은 학습에 의해 이끌렸습니다. 그리고 React 팀의 많은 구성원들로부터 상당한 도움과 기여를 받았습니다.

이 안정 릴리스는 많은 것들 중 첫 걸음입니다. 컴파일러는 계속 진화하고 개선될 것이며, 앞으로 10년 이상 React의 새로운 기반과 시대가 될 것으로 기대합니다.

바로 빠른 시작으로 이동하거나, React Conf 2025의 하이라이트를 계속 읽어보세요.

[Deep Dive] React Compiler는 어떻게 작동하나요?

React Compiler는 자동 메모이제이션을 통해 컴포넌트와 훅을 최적화하는 최적화 컴파일러입니다. 현재는 Babel 플러그인으로 구현되어 있지만, 컴파일러는 대체로 Babel과 분리되어 있으며, Babel이 제공하는 추상 구문 트리(AST)를 자체의 새로운 HIR로 낮추고, 여러 컴파일러 패스를 통해 React 코드의 데이터 흐름과 변경 가능성을 세심하게 이해합니다. 이를 통해 렌더링에 사용되는 값을 세분화하여 메모이제이션할 수 있으며, 수동 메모이제이션으로는 불가능한 조건부 메모이제이션도 가능합니다.

import { use } from 'react';

export default function ThemeProvider(props) {
  if (!props.children) {
    return null;
  }
  // The compiler can still memoize code after a conditional return
  const theme = mergeTheme(props.theme, use(ThemeContext));
  return (
    <ThemeContext value={theme}>
      {props.children}
    </ThemeContext>
  );
}

이 예시는 React Compiler Playground에서 확인하세요

자동 메모이제이션 외에도, React Compiler에는 React 코드에서 실행되는 검증 패스가 있습니다. 이 패스는 React의 규칙을 인코딩하고, 컴파일러가 데이터 흐름과 변경 가능성을 이해하는 능력을 활용하여 React의 규칙이 깨진 지점을 진단합니다. 이러한 진단은 종종 React 코드에 숨은 잠재적 버그를 드러내며, 주로 eslint-plugin-react-hooks를 통해 노출됩니다.

컴파일러가 코드를 어떻게 최적화하는지 더 알고 싶다면 Playground를 방문하세요.

오늘 바로 React Compiler 사용하기

컴파일러를 설치하려면:

# npm
npm install --save-dev --save-exact babel-plugin-react-compiler@latest

# pnpm
pnpm add --save-dev --save-exact babel-plugin-react-compiler@latest

# yarn
yarn add –dev –exact babel-plugin-react-compiler@latest

안정 릴리스의 일환으로, 우리는 React Compiler를 프로젝트에 더 쉽게 추가할 수 있도록 하고 컴파일러가 메모이제이션을 생성하는 방식에 최적화를 추가했습니다. 이제 React Compiler는 의존성으로서 옵셔널 체인과 배열 인덱스를 지원합니다. 이러한 개선은 궁극적으로 리렌더를 줄이고 더욱 반응성 높은 UI를 제공하며, 익숙한 선언적 코드를 계속 작성할 수 있게 합니다.

컴파일러 사용에 대한 더 자세한 내용은 문서에서 확인할 수 있습니다.

프로덕션에서의 관측

컴파일러는 이미 Meta Quest Store 같은 앱에 배포되었습니다. 초기 로드와 페이지 간 내비게이션이 최대 12% 개선되었고, 특정 상호작용은 2.5배 이상 빨라졌습니다. 이러한 성과에도 불구하고 메모리 사용량은 중립적입니다. 결과는 달라질 수 있지만, 앱에서 컴파일러를 실험하여 비슷한 성능 향상을 확인해 보시길 권장합니다.

하위 호환성

베타 발표에서 언급했듯이, React Compiler는 React 17 이상과 호환됩니다. 아직 React 19를 사용하지 않는 경우, 컴파일러 설정에서 최소 타겟을 지정하고 react-compiler-runtime을 의존성으로 추가하면 React Compiler를 사용할 수 있습니다. 이에 대한 문서는 여기에서 확인할 수 있습니다.

컴파일러 기반 린팅으로 React의 규칙을 강제하세요

React Compiler에는 React의 규칙을 위반하는 코드를 식별하는 데 도움이 되는 ESLint 규칙이 포함되어 있습니다. 린터는 컴파일러 설치를 필요로 하지 않으므로, eslint-plugin-react-hooks를 업그레이드하는 데 위험이 없습니다. 모든 분들께 오늘 업그레이드를 권장합니다.

이미 eslint-plugin-react-compiler를 설치했다면, 이제 이를 제거하고 eslint-plugin-react-hooks@latest를 사용하면 됩니다. 이 개선에 기여해 주신 @michaelfaith께 큰 감사를 드립니다!

설치 방법:

# npm
npm install --save-dev eslint-plugin-react-hooks@latest

# pnpm
pnpm add --save-dev eslint-plugin-react-hooks@latest

# yarn
yarn add --dev eslint-plugin-react-hooks@latest
// eslint.config.js (Flat Config)
import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config';

export default defineConfig([
  reactHooks.configs.flat.recommended,
]);
// eslintrc.json (Legacy Config)
{
  "extends": ["plugin:react-hooks/recommended"],
  // ...
}

React Compiler 규칙을 활성화하려면 recommended 프리셋 사용을 권장합니다. 더 자세한 지침은 README를 확인하세요. 여기 React Conf에서 소개한 몇 가지 예시가 있습니다:

  • set-state-in-render로 렌더 루프를 유발하는 setState 패턴을 포착합니다.
  • set-state-in-effect로 이펙트 내부의 비용 높은 작업을 경고합니다.
  • refs로 렌더 중 안전하지 않은 ref 접근을 방지합니다.

useMemo, useCallback, React.memo는 어떻게 해야 하나요?

기본적으로, React Compiler는 분석과 휴리스틱에 따라 코드의 메모이제이션을 수행합니다. 대부분의 경우, 이 메모이제이션은 여러분이 작성했을 법한 것만큼 또는 그보다 더 정밀하며 — 위에서 언급했듯이, 컴파일러는 조기 반환 이후와 같이 useMemo/useCallback을 사용할 수 없는 경우에도 메모이제이션을 수행할 수 있습니다.

다만, 경우에 따라 개발자가 메모이제이션에 대해 더 많은 제어를 필요로 할 수 있습니다. useMemouseCallback 훅은 React Compiler와 함께 계속 사용할 수 있는 탈출구로서, 어떤 값이 메모이제이션되는지에 대해 제어를 제공합니다. 일반적인 사용 사례로는 메모이제이션된 값이 이펙트 의존성으로 사용되는 경우가 있는데, 의미 있게 변경되지 않는 의존성에도 이펙트가 반복적으로 실행되지 않도록 보장하기 위함입니다.

새로운 코드에서는 메모이제이션을 컴파일러에 맡기고, 정밀한 제어가 필요할 때 useMemo/useCallback을 사용하는 것을 권장합니다.

기존 코드의 경우, 기존 메모이제이션을 그대로 유지하는 것을 권장합니다(이를 제거하면 컴파일 결과가 달라질 수 있음) 또는 메모이제이션을 제거하기 전에 신중하게 테스트하십시오.

새로운 앱은 React Compiler를 사용해야 합니다

우리는 Expo, Vite, Next.js 팀과 협력하여 새로운 앱 경험에 컴파일러를 추가했습니다.

Expo SDK 54이상에서는 기본적으로 컴파일러가 활성화되어 있으므로, 새로운 앱은 처음부터 자동으로 컴파일러의 이점을 활용할 수 있습니다.

npx create-expo-app@latest

Vite 및 Next.js 사용자는 create-vitecreate-next-app에서 컴파일러가 활성화된 템플릿을 선택할 수 있습니다.

npm create vite@latest
npx create-next-app@latest

점진적으로 React Compiler 도입

기존 애플리케이션을 유지 관리 중이라면, 원하는 속도로 컴파일러를 롤아웃할 수 있습니다. 우리는 점진적 도입 가이드를 단계별로 공개했으며, 게이트 전략, 호환성 검사, 롤아웃 도구를 다뤄 컴파일러를 자신 있게 활성화할 수 있도록 돕습니다.

swc 지원(실험적)

React Compiler는 Babel, Vite, Rsbuild 등 여러 빌드 도구에서 설치할 수 있습니다.

이들 도구 외에도, 우리는 swc팀의 Kang Dongyoon (@kdy1dev과 협업하여 React Compiler를 swc 플러그인으로 추가하는 추가 지원을 진행 중입니다. 이 작업은 아직 완료되지 않았지만, Next.js 앱에서 React Compiler를 활성화하면 이제 Next.js 빌드 성능이 상당히 빨라져야 합니다.

최상의 빌드 성능을 얻으려면 Next.js 15.3.1 이상을 사용할 것을 권장합니다.

Vite 사용자는 vite-plugin-react를 계속 사용하여 컴파일러를 활성화할 수 있으며, 이를 Babel 플러그인으로 추가하면 됩니다. 우리는 또한 oxc팀과 협력하여 컴파일러 지원 추가를 진행 중입니다. rolldown이 공식적으로 릴리스되어 Vite에서 지원되고 oxc가 React Compiler를 지원하게 되면, 마이그레이션 방법에 대한 정보를 문서에 업데이트할 것입니다.

React Compiler 업그레이드

React Compiler는 자동 메모이제이션이 오로지 성능을 위해 적용될 때 가장 잘 작동합니다. 향후 버전의 컴파일러는 메모이제이션 적용 방식이 변경될 수 있으며, 예를 들어 더 세분화되고 정밀해질 수 있습니다.

그러나 제품 코드가 때때로 JavaScript에서 항상 정적으로 감지될 수 없는 방식으로 React의 규칙을 깨뜨리는 경우가 있기 때문에, 메모이제이션 변경은 때로 예상치 못한 결과를 초래할 수 있습니다. 예를 들어, 이전에 메모이제이션된 값을 컴포넌트 트리 어딘가의 useEffect 의존성으로 사용할 수 있습니다. 이 값이 어떻게 또는 메모이제이션되는지 변경되면 해당 useEffect가 과도하게 실행되거나 충분히 실행되지 않을 수 있습니다. 우리는 useEffect는 동기화에만 사용할 것을 권장하지만, 여러분의 코드베이스에는 특정 값 변경에만 반응하여 실행되어야 하는 이펙트처럼 다른 사용 사례를 다루는 useEffect가 있을 수 있습니다.

다시 말해, 메모이제이션 변경은 드문 경우에 예기치 않은 동작을 유발할 수 있습니다. 이러한 이유로, 우리는 React의 규칙을 따르고 앱의 연속적인 종단간 테스트를 수행하여 컴파일러를 자신 있게 업그레이드하고 문제를 일으킬 수 있는 React 규칙 위반을 식별할 것을 권장합니다.

테스트 커버리지가 충분하지 않은 경우, 컴파일러 버전을 SemVer 범위(예: ^1.0.0)가 아니라 정확한 버전(예: 1.0.0)으로 고정하는 것을 권장합니다. 컴파일러를 업그레이드할 때 --save-exact(npm/pnpm) 또는 --exact(yarn) 플래그를 사용하면 됩니다. 이후 컴파일러 업그레이드는 수동으로 수행하고, 앱이 예상대로 작동하는지 확인하는 데 주의를 기울여야 합니다.

이 글을 검토하고 편집해 주신 Jason Bonta, Jimmy Lai, Kang Dongyoon (@kdy1dev), Dan Abramov께 감사드립니다.

Edit this page