React Native 0.76 - New Architecture by default, React Native DevTools, and more
오늘, 우리는 React Native 0.76을 출시하게 되어 매우 기쁘게 생각한다.
이번 릴리스는 React Native의 주요 이정표다. 기본적으로 새로운 아키텍처를 활성화하고 React Native DevTools를 소개한다. 이는 우리 팀의 6년 간의 노력과 놀라운 개발자 커뮤니티의 지원이 결실을 맺은 결과다.
주요 내용
주요 변경 사항
- react-native-community/cli 의존성 제거
- 네이티브 라이브러리 병합으로 안드로이드 앱 크기 약 3.8MB 감소
- 최소 iOS 및 Android SDK 요구 사항 업데이트
주요 내용
React Native 신규 아키텍처 기본 적용
React Native 0.76 버전부터 프로젝트에서 신규 아키텍처가 기본적으로 활성화된다. 신규 아키텍처는 React Native의 내부 구조를 재구성해 앱 개발자가 React를 사용해 고품질의 네이티브 애플리케이션을 개발할 수 있도록 지원한다.
이제 신규 아키텍처가 프로덕션 환경에서 사용할 준비가 되었다고 발표한다.
이번 변경은 React Native의 발전 과정에서 중요한 이정표다. 신규 아키텍처가 어떤 내용을 포함하고, React Native의 미래를 어떻게 이끌어갈지 자세히 알아보려면 관련 블로그 포스트를 읽어보길 권한다: 신규 아키텍처가 도입되었다.
React Native DevTools
React Native DevTools의 첫 번째 안정 버전을 출시한다. 이는 새로운 기본 디버깅 환경이다.
모든 플랫폼에서 React를 디버깅할 때 사용하는 도구가 신뢰할 수 있고, 익숙하며, 간단하고, 일관성 있기를 바란다. React Native DevTools는 이러한 원칙을 충족한다. React Native와 깊이 통합된 브라우저 기반 개발자 도구이다. 주요 기능은 다음과 같다:
- 익숙한 웹 기반 도구 — Chrome DevTools를 기반으로 한 완벽한 디버거로, 신뢰할 수 있는 중단점, 감시 값, 단계별 디버깅, 스택 검사, 그리고 풍부한 JavaScript 콘솔을 제공한다. 이러한 핵심 기능은 이제 리로드 시에도 안정적으로 작동한다.
- 개선된 React DevTools 통합 — 내장된 React 컴포넌트 검사기와 프로파일러가 더 빠르고 안정적으로 작동하며, 컴포넌트 강조 기능도 개선되었다.
- 개선된 사용자 경험 — 새로운 Paused in Debugger 오버레이를 통해 중단점에서 앱이 멈췄을 때를 명확히 알 수 있다. LogBox의 경고는 이제 요약 형태로 표시되며, DevTools가 연결되면 숨겨진다.
- 재연결 동작 수정 — JavaScript 중단점은 이제 리로드 시나 DevTools가 연결 해제되고 다시 연결될 때도 안정적으로 작동한다. DevTools는 네이티브 재빌드 후에도 동일한 앱에 다시 연결할 수 있다.
- 즉시 실행 — React Native DevTools는 기본적으로 설정 없이 바로 사용할 수 있다. 앱 내 Dev 메뉴에서 열거나 j를 눌러 CLI 서버에서 디버깅할 수 있다. 이제 여러 에뮬레이터와 디바이스를 지원한다.
React Native DevTools는 이전 디버깅 옵션과 근본적으로 다르다. 0.73 버전에서 처음 출시된 실험적 디버거 경험과도 차이가 있다. 지난 1년 동안 재구축한 새로운 백엔드 디버깅 스택으로 전환했다. 이는 이전 도구와의 호환성이 변경되었음을 의미하며, 엔드투엔드로 훨씬 더 안정적인 경험을 기대할 수 있다. 이 새로운 스택을 기반으로 Performance 및 Network 패널과 같은 더 많은 기능을 신뢰성 있게 구현할 계획이다.
Metro에서 로그 기능 단계적 폐지
다음 릴리스에서 Metro의 전달 로그 기능을 제거한다. 이는 모던 브라우저 도구와의 일관성을 유지하고 오래된 디버깅 통합을 제거하기 위함이다. 대신 React Native DevTools의 완전한 기능을 갖춘 Console 패널을 사용해 로깅을 진행한다. 자세한 내용은 FAQ를 참고한다.
관련 링크
Metro의 빠른 모듈 해석
Metro의 리졸버 성능을 크게 개선했다. 리졸버는 import 경로에서 모듈을 찾는 역할을 하는 컴포넌트로, 이번 업데이트로 약 15배 빠르게 동작한다. 이로 인해 Metro의 전반적인 성능이 향상되었으며, 특히 웜 빌드(warm builds)에서 약 4배 빠른 속도를 확인할 수 있다.
박스 그림자와 필터 스타일 속성
0.76 버전에서 boxShadow
와 filter
라는 두 가지 새로운 스타일 속성을 추가했다. 이 두 속성은 웹에서도 사용되며, 팀은 가능한 한 스펙을 준수해 속성이 예측 가능하고 익숙하며 최종적으로 도입하기 쉽도록 했다 (예외 사항은 제한 사항 및 스펙 차이 부분을 참고).
결과적으로, 이 속성들이 어떻게 동작하는지 완전히 이해하려면 웹 문서를 참고하면 되지만, 아래에 몇 가지 중요한 차이점을 정리했다.
boxShadow
boxShadow
는 엘리먼트에 그림자를 추가하며, 그림자의 위치, 색상, 크기, 흐림 정도를 조절할 수 있다. 각 인자에 대한 자세한 설명과 직접 실습해 볼 수 있는 예제는 MDN 문서를 참고한다. 아래는 다양한 그림자 스타일의 예시다.
boxShadow
는 CSS 구문을 모방한 문자열이나 변수를 포함할 수 있는 JS 객체를 인자로 받는다. 예를 들어, 문자열 ‘5 5 5 0 rgba(255, 0, 0, 0.5)’
와 객체 {offsetX: 5, offsetY: 5, blurRadius: 5, spreadDistance: 0, color: ‘rgba(255, 0, 0, 0.5)’}
는 동일한 박스 그림자를 생성한다.
이전의 그림자 기능은 몇 가지 한계가 있었는데, boxShadow
가 이를 해결했다:
- 안드로이드에서 작동하지 않던 문제
- 내부 그림자(inset)를 지원하지 않던 문제
- 확장(spread) 기능이 없던 문제
- 배경색이 없는
View
에서 작동하지 않던 문제 - 별도의 프로퍼티로 분리되어 웹 구문과 호환되지 않던 문제
제한 사항 및 스펙 차이
- 기본 그림자 색상은 부모 엘리먼트의 색상이 아니라 검정색이다.
- 일반 안드로이드 그림자는 안드로이드 9 이상에서만 지원된다.
- 안드로이드 내부 그림자는 안드로이드 10 이상에서만 지원된다.
filter
filter
는 엘리먼트에 특정 그래픽 필터를 추가한다. 색상 필터는 밝기, 채도, 색상 등을 조정할 수 있고, 비색상 필터는 블러와 그림자 효과를 적용할 수 있다. 각 필터 함수에 대한 자세한 내용은 MDN 문서를 참고하고, 직접 실습해 볼 수 있는 예제도 확인할 수 있다. 아래는 다양한 필터가 적용된 핫도그 이미지 예제이다.

saturate
필터, blur
필터, invert
필터boxShadow
와 마찬가지로, filter
는 CSS 구문을 모방한 문자열이나 변수를 포함할 수 있는 JS 객체 배열을 인자로 받는다. 예를 들어, 문자열 ‘saturate(0.5) grayscale(0.25)’
와 배열 [{saturate: 0.5}, {grayscale: 0.25}]
는 동일한 필터를 생성한다.
filter
에는 boxShadow
와 약간 다른 dropShadow
값이 있다. 가장 큰 차이점은 dropShadow
가 알파 마스크라는 점이다. 즉, 픽셀의 알파 값이 0이 아닌 경우에만 그림자가 생성된다. 반면 boxShadow
는 엘리먼트 내부에 아무것도 없더라도 테두리 박스 주변에 그림자를 만든다. 또한 dropShadow
는 퍼짐 거리(spread distance) 매개변수가 없고, 내부에 그림자를 생성하는 inset 기능도 지원하지 않는다.
제한 사항과 스펙 차이
- iOS의
filter
는 밝기와 불투명도만 지원한다. - iOS의
filter
는 엘리먼트 경계 밖에 있는 그림자, 윤곽선 또는 기타 그래픽 요소에는 적용되지 않는다. - Android의
blur
와drop-shadow
는 Android 12 이상에서만 지원된다. filter
는overflow: hidden
을 암시한다. 따라서filter
가 적용된 엘리먼트의 자식 요소가 부모 경계 밖에 위치하면 잘리게 된다.
주요 변경 사항
@react-native-community/cli 의존성 제거
이전에 0.75 버전에서 공유했듯이, React Native를 프레임워크 독립적으로 만드는 것이 우리의 목표다. 이를 위해 React Native에서 @react-native-community/cli를 직접적인 의존성으로부터 제거하는 작업을 완료했다.
React Native와 CLI를 분리하면 각 프로젝트를 독립적으로 릴리스할 수 있고, 두 프로젝트의 책임을 더 명확히 구분할 수 있다.
만약 여러분의 일상적인 워크플로우에서 CLI에 의존하고 있다면, package.json
에 CLI 의존성을 명시적으로 추가해야 한다:
//…
“devDependencies”: {
// …
+ “@react-native-community/cli”: “15.0.0”,
+ "@react-native-community/cli-platform-android": “15.0.0”,
+ "@react-native-community/cli-platform-ios": “15.0.0”,
},
네이티브 라이브러리 병합으로 Android 앱 크기가 약 3.8MB 감소
React Native 0.76 버전에서는 네이티브 라이브러리 수가 줄어들며, 많은 네이티브 코드가 단일 라이브러리인 libreactnative.so
로 병합된다.
이 변경으로 Android 앱의 크기가 감소하고 앱 시작 성능이 개선된다. 벤치마크 결과에 따르면, 앱 크기는 약 3.8MB(전체의 20%) 감소하고, 앱 시작 시간 중앙값은 약 15ms(약 8%) 단축된다(출처).
반면, 이 변경은 앱 개발자와 라이브러리 개발자 모두에게 주요 변경 사항이다.
앱 개발자는 다음과 같이 Application의 onCreate
를 업데이트해야 한다:
+import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
class MainApplication : Application(), ReactApplication {
override fun onCreate() {
super.onCreate()
+ SoLoader.init(this, OpenSourceMergedSoMapping)
- SoLoader.init(this, false)
}
}
이 변경은 libreactnative.so
를 올바르게 로드하기 위해 필요하며, 업그레이드 헬퍼에 포함되어 있다.
라이브러리 작성자는 커스텀 C++ 코드가 없는 한 이 변경의 영향을 받지 않는다.
이 변경에 대한 기술적 심층 분석과 라이브러리 작성자를 위한 제안은 전용 포스트에서 더 자세히 확인할 수 있다.
최소 iOS 및 Android SDK 요구 사항 업데이트
최소 플랫폼 및 SDK 버전을 다음과 같이 업데이트했다:
이 변경 사항은 올해 초 0.75 버전 출시 시점에 발표되었다. 자세한 배경 정보는 Android와 iOS 관련 포스트를 참고한다.
주요 변경 사항
-
애니메이션
- 반복 애니메이션에서 React로 상태 업데이트를 보내지 않도록 변경했다. 이로 인해 반복 애니메이션에서 불필요한 리렌더링이 발생하는 문제를 해결했다.
-
개발 도구(devtools)
- New Arch에서 Inspector Panel의 성능 및 네트워크 탭을 제거했다. (RFC)
-
텍스트 엔진
- TextLayoutManager에서 항상 AttributedStringBox를 사용하도록 변경했다. 이전에는 AttributedString을 사용했으나, 이제는 AttributedStringBox로 통일했다.
Android
- 렌더링:
- 뷰 배경은 더 이상 직접
ReactViewBackgroundDrawable
이나CSSBackgroundDrawable
을 사용하지 않는다.
- 뷰 배경은 더 이상 직접
iOS
- turbomodule
- 순수 Cxx 모듈 자동 연결을 위한
RCT_EXPORT_CXX_MODULE_EXPERIMENTAL
매크로를 제거했다.
- 순수 Cxx 모듈 자동 연결을 위한
감사의 말
React Native 0.76에는 156명의 기여자가 만든 1070개 이상의 커밋이 포함되어 있다. 모두의 노고에 감사드린다!
이번 릴리스 포스트에서 기능 문서화 작업에 참여한 추가 저자들에게도 감사드린다:
- Joe Vilches와 Nick Gerleman - box-shadow 및 filter 스타일 프로퍼티
- Alex Hunt - React Native DevTools
- Nicola Corti - Android 단일 라이브러리로 배포
0.76 버전으로 업그레이드
기존 프로젝트를 React Native 버전 간 코드 변경 사항을 확인하려면 React Native Upgrade Helper를 사용하세요. 업그레이드 문서와 함께 활용하면 도움이 됩니다.
Expo를 사용하는 경우, React Native 0.76은 Expo SDK 52에서 지원됩니다.
CLI를 통해 새 프로젝트를 생성하려면 다음 명령어를 실행하세요:
npx @react-native-community/cli@latest init MyProject --version latest
0.76 버전이 현재 React Native의 최신 안정 버전이며, 0.73.x 버전은 지원이 중단되었습니다. 자세한 내용은 React Native의 지원 정책을 참고하세요. 0.73 버전의 최종 종료 업데이트를 곧 제공할 예정입니다.