- 웹 중심 회사인 Vercel이 Apple Design Award급 네이티브 경험을 목표로 여러 기술 스택과 UI 패턴을 실험한 끝에 React Native + Expo 조합으로 완성
- 핵심은 메모처럼 아이디어를 적으면 백그라운드에서 만들어지는 AI 채팅 기반 제작 경험으로, 메시지 애니메이션·스크롤·키보드·Liquid Glass 컴포저까지 세밀하게 설계해 iOS 네이티브 수준의 채팅 인터랙션을 구현
- 채팅 구현에서는 LegendList, Reanimated, react-native-keyboard-controller를 기반으로 한 컨텍스트·훅 조합, blankSize와 contentInset 계산, composer 높이 연동 등으로 동적 높이와 키보드 변화를 부드럽게 처리
- 코드 구조는 웹과 네이티브 간에 타입·비즈니스 로직·API 레이어를 공유하고, Zod 기반 OpenAPI 스키마 → Hey API → Tanstack Query 흐름으로 v0 웹과 v0 Platform API 고객이 같은 엔드포인트를 쓰도록 설계한 점이 특징
v0 iOS 앱 개요와 목표
- Vercel은 자사 첫 모바일 앱인 v0 for iOS를 출시하며, 웹 중심 회사임에도 Apple Design Award를 목표로 한 고품질 네이티브 경험을 만드는 것을 목표로 잡았음
- iOS 앱 출시 전까지는 웹에 집중해 왔기 때문에, 완전한 네이티브 앱 개발은 새로운 영역이었음
- 이를 위해 공개 베타 이전에 여러 다른 기술 스택과 UI 패턴을 적용한 수십 가지 버전을 실험함
- 레퍼런스로는 Apple Notes, iMessage처럼 아이폰의 언어를 잘 쓰는 앱들에서 영감을 받아, 홈 화면의 다른 앱들 사이에서 자리를 차지할 수 있을 수준의 완성도를 요구했음
- 특정 프레임워크에 고정되지 않고, 여러 스택을 실제로 구현·비교한 후 결론을 내렸다고 설명함
- 여러 실험 끝에 최종적으로 React Native + Expo를 선택했고, 결과적으로 네이티브 앱처럼 느껴진다는 개발자들의 피드백이 많이 들어와 이를 계기로 상세 기술 구조를 공개함
v0 채팅 경험의 방향
- v0 iOS는 “컴퓨터에서 떨어져 있을 때 떠오른 아이디어를 바로 실행 가능한 것으로 만드는 도구”를 목표로, 메모 앱의 다음 세대라는 위치를 지향
- 웹과 같은 모바일 IDE나 전체 기능을 옮기는 것보다, 이동 중 AI로 무언가를 만들 수 있는 간단하고 즐거운 경험을 우선함
- 이 경험의 중심은 채팅 인터페이스이며, 이에 대해 다음과 같은 요구사항을 정리
- 새 메시지는 부드럽게 애니메이션으로 나타날 것
- 새 사용자 메시지는 화면 상단까지 스크롤되어 보일 것
- 어시스턴트 메시지는 스트리밍되면서 계단식 페이드 인(스트리밍 + 지연) 으로 표시될 것
- 입력창(컴포저)은 Liquid Glass 스타일로 떠 있으며, 스크롤 가능한 콘텐츠 위에 떠 있을 것
- 기존 채팅을 여는 경우 마지막 메시지까지 스크롤된 상태로 시작할 것
- 키보드 동작은 자연스럽고 네이티브에 가깝게 느껴질 것
- 텍스트 입력은 이미지·파일 붙여넣기와 팬 제스처 포커스/블러를 지원할 것
-
Markdown 렌더링은 빠르면서 동적 컴포넌트도 지원할 것
- 모바일에서의 AI 채팅 UI 패턴은 많지만, AI 코드 생성용 모바일 패턴은 부재했기 때문에 새 패턴을 직접 설계해야 했고, 기준에 맞추기 위해 상당한 작업·테스트·조율이 필요했음
컴포저블 채팅 구조 설계
- 채팅 요구사항을 만족시키기 위해, 채팅 코드는 기능별로 조합 가능(composable) 하게 설계함
- 이를 위해 채팅 전체를 감싸는 여러 Context Provider를 만든 후, 메시지 리스트를 이 안에 두는 구조를 사용
- 채팅 구현에는 다음과 같은 오픈소스 라이브러리를 사용함
-
LegendList: 고성능 리스트 렌더링
-
React Native Reanimated: 애니메이션과 공유 값(shared value)
-
react-native-keyboard-controller: 키보드 상태 제어 및 이벤트 핸들링
- 각 메시지 렌더링은 item.role에 따라 user / assistant / optimistic-placeholder로 분기해, 역할별로 다른 컴포넌트를 사용함
메시지 애니메이션 구현
- 첫 사용자 메시지는 Reanimated 공유값(shared value) 을 이용해 부드럽게 페이드 인
-
useFirstMessageAnimation 훅이 메시지 높이·화면 높이·키보드 높이를 계산해 translateY와 opacity를 제어
- 첫 번째 어시스턴트 메시지는 사용자 메시지 애니메이션 완료 후 지연 페이드 인
- 기존 채팅에서는 scrollToEnd()와 contentInset 조정으로 새 메시지를 화면 상단에 자연스럽게 배치
스크롤 및 키보드 제어
- 채팅 경험의 품질은 키보드 동작의 자연스러움에 크게 의존하며, React Native에서 네이티브에 가까운 키보드 감각을 만드는 작업은 상당히 까다로웠음
- iOS 버전별 차이로 인해 키보드 동작 불안정 문제가 발생,
react-native-keyboard-controller 유지관리자와 협력해 버그 수정 및 성능 개선
-
useKeyboardAwareMessageList 훅으로 키보드 열림·닫힘·드래그 이벤트를 세밀하게 제어
- 기존 채팅 열기 시 자동 스크롤 위치 조정을 위해 scrollToEnd를 여러 번 호출하여 동적 높이 문제 해결
Liquid Glass Floating Composer와 입력창 개선
- iMessage의 Liquid Glass 효과를 적용해 반투명·부유형 입력창 구현
-
KeyboardStickyView와 composerHeight 공유값으로 스크롤뷰 contentInset을 실시간 조정
- 입력창 높이 변화 시 자동 스크롤을 유지하기 위해 useScrollWhenComposerSizeUpdates 훅 사용
- 기본 TextInput의 스크롤 바운스·지표 노출 문제를 해결하기 위해 RCTUITextView 네이티브 패치 적용
- 스와이프 제스처로 키보드 포커스 가능하도록 개선
이미지 붙여넣기 및 스트리밍 콘텐츠 페이드 인
-
Expo 모듈을 통해 UIPasteboard 이벤트를 감지, 텍스트·이미지·파일 붙여넣기 지원
-
FadeInStaggeredIfStreaming 컴포넌트를 사용해 AI 응답 텍스트의 단어 단위 페이드 인 구현
- 애니메이션 풀(pool) 관리로 동시 애니메이션 개수 제한 및 성능 최적화
- 이미 본 콘텐츠는 DisableFadeProvider로 재애니메이션 방지
웹과 네이티브 간 코드 공유와 Platform API
- 웹과 모바일 간 타입·헬퍼 함수 공유, UI·상태 관리는 분리
-
Zod 기반 타입 안전 API 프레임워크 구축, OpenAPI 스펙을 자동 생성
- 모바일 앱은 Hey API + Tanstack Query로 API 호출
- 이 구조를 기반으로 v0 Platform API를 공개, 동일한 엔드포인트를 외부 개발자에게 제공
스타일링 및 네이티브 컴포넌트
-
react-native-unistyles로 테마 관리, Context 접근 없이 빠른 스타일링 지원
-
Zeego를 통해 iOS 네이티브 UIMenu 기반 메뉴 구현
- iOS 26에서 발생한 Alert 위치 오류를 수정하고 React Native에 패치 업스트림 기여
-
모달(formSheet) 관련 드래그·플리커링 문제를 수정, Callstack·Meta·Expo와 협력해 React Native 0.82에 반영
앞으로의 계획과 커뮤니티 협업
-
React Native + Expo 조합으로 첫 앱을 완성한 후, 향후 프로젝트도 동일 스택 유지 예정. 현재 스택에 만족하고 있음
- Vercel은 야심찬 제품을 높은 수준으로 구현하는 데 집중하고 있으며,
- 웹·네이티브 개발자가 같은 수준의 제품을 만들 수 있도록 내부에서 구축한 노하우를 오픈소스로 공개할 계획이라고 밝힘
- 특히 AI 채팅 앱용 오픈소스 라이브러리를 베타 테스트할 커뮤니티를 모집하고 있으며, React Native 개선에 계속 기여할 것