서서히 유저를 끌어모으던 웹 서비스가 있었습니다. Next.js로 잘 돌아가던 B2B 서비스였죠. 모바일 웹에서도 핵심 플로우는 이미 잘 동작하고 있었습니다. 그런데 VOC를 살펴보다가 고민에 빠졌습니다. 알림을 보지 못해서 계약이 불발되었다는 내용이었습니다. 웹에서는 항상 보이는 헤더의 알림창이 서비스를 벗어나면, 더이상 쉽게 볼 수 없는 정보가 됐습니다. 그래서 앱을 만드는 것에 대해 고민하기 시작했죠.
앱을 만드는 건 생각보다 많은 시간이 걸립니다. 하지만 이미 잘 정리된 모바일 웹이 있으니, 이걸 기반으로 AI에게 시키면 잘 만들어주지 않을까?라는 생각을 하게 된 거죠. 결론부터 미리 말하자면, 생각보다 더 잘 만들어줬습니다. 이 글의 제목처럼 일주일 만에 POC수준 이상의 앱을 만들었고, 지금은 QA를 거치는 중입니다.
그래서 이번 글에서는 모바일 웹을 앱으로 바꾸는 과정에서 부딪힌 이슈와, 이를 위해 어떤 워크플로우를 도입했고, 어떻게 기술 스택을 선정했는지에 대한 얘기를 풀어보고자 합니다.
최근에 Shopify 엔지니어링 블로그의 “Native is now the future of mobile at Shopify”를 읽었습니다. 한 줄로 말하면, Shopify가 앱을 React Native에서 Swift와 Kotlin 네이티브로 되돌린다는 내용입니다.
흥미로운 지점은 “RN(React Native)이 실패해서”가 아니라는 데 있습니다. 글에서도 2020년 RN 올인은 매우 성공적이었다고 말합니다. 기능을 한 번만 만들고, 모바일 배경이 없는 개발자도 기여할 수 있게 하고, 플랫폼 간 패리티 추격에 덜 매달리게 해 주었다는 거죠. 그런데 코딩 에이전트(LLM)가 좋아지면서, 같은 기능을 두 번 만드는 비용이라는 가정이 흔들렸다고 합니다. 에이전트가 iOS를 보고 Android를 구현하거나, 그 반대를 할 수 있고, 공유 스펙·테스트·리뷰로 패리티 유지비가 예전만큼 무겁지 않다는 실험이 나왔다는 이야기입니다. 그래서 플랫폼에 더 가까운 네이티브가, 지금 Shopify 규모에서는 다시 합리적이 되었다는 결론으로 갑니다.
Shop 앱은 AI를 도우미로 두고, 약 12주 만에 네이티브로 재구축해 스토어에 올렸다는 대목도 인상적이었습니다. Helix 같은 체크포인트 루프로 “한 방에 네이티브 번역”이 아니라, 작은 단위로 검증하며 옮긴다는 점도요. 이 글을 읽고 나면, 2026년에 React Native를 고르는 일이 어쩐지 시대를 역행하는 선택처럼 느껴질 수 있습니다. 큰 회사들이 다시 네이티브로 가는 타이밍에, 저는 Expo 기반 RN으로 POC를 시작했으니까요.
그럼에도 저는 RN을 골랐습니다. Shopify의 결론을 부정해서가 아니라, 전제가 달랐기 때문입니다.
Shopify는 여러 대형 앱과 수백 명의 엔지니어, 이미 쌓인 RN 자산과 네이티브 전환을 감당할 조직이 있습니다. 저는 사실상 1인에 가까운 프론트엔드로, 이미 돌아가는 Next.js 웹과 같은 제품 언어를 최대한 공유해야 했습니다. Swift와 Kotlin을 동시에 새로 배우고, 웹까지 세 갈래로 의미를 맞추는 일은 일주일 POC의 목표가 아니었습니다.
제가 원한 공유는 단순히 UI에만 국한되지 않고, 가입 스키마, 에러 카피, API 훅, 폼 검증처럼 의미의 코드베이스를 웹과 앱이 같이 쓰는 쪽이었습니다. React 문법을 아는 상태에서 RN(Expo)으로 가면, AI 에이전트에게도 “웹 모바일 화면을 보고 앱 화면을 조립해”라는 지시가 통합니다. 같은 훅, 같은 zod, 같은 도메인 단어를 유지한 채 화면 단위로 옮길 수 있었죠. 네이티브 두 플랫폼을 AI가 잘 옮겨 준다는 Shopify의 논리와는 결이 다르지만, 이미 있는 React 웹을 SoT(Single source of Truth)로 삼아 한 사람이 개발해야 하는 상황에서는 RN이 훨씬 저에겐 합리적인 선택이었습니다.
이전에 AI 에이전트에게도 “웹 모바일 화면을 보고 앱 화면을 조립해”라는 지시가 통하게 하려면 웹 모바일 화면에 대한 충분한 컨텍스트를 제공할 수 있어야합니다. 그래서 기존 프로젝트를 모노레포로 옮기는 작업을 먼저 시작했습니다.
전체적인 구조는 다음과 같은데요. pnpm workspace로 apps/*와 packages/*를 나눴습니다.
apps 내부에는 “web”, “admin”, “mobile” 이렇게 3개의 프로젝트가 있고, packages 아래 이미지처럼 생겼습니다.

이렇게 앱과 패키지를 나눈 세세한 이유는 없습니다. 단지 공유가능한 단위를 패키지로 옮기다보니, 이렇게 점점 생기고 있을 뿐입니다. 만약 추가로 옮겨야 하는 것들이 있다면 패키지에 추가하면 됩니다. 지금 떠오르는 후보는 Grafana, Sentry처럼 에러 로깅 시스템을 패키지화하면 좋지 않나라는 생각이 드네요.
패키지 표를 보면 UI의 핵심이 되는 축이 세 개로 보입니다. @chulgang/ui, @chulgang/ui-native, @chulgang/tokens입니다. 특히 ui와 ui-native로 나뉘어 있는 것을 눈여겨봐 주셨으면 합니다.
저는 웹과 앱을 한 레포에 두더라도, UI를 억지로 하나의 패키지로 묶으면 오히려 비용이 커질 거라고 생각했습니다. 하나의 패키지로 웹이랑 앱을 다 커버하는 일은 무리에 가깝다는 쪽이었습니다.
처음 구상할 때는 당연히 욕심이 났습니다. 웹도 앱도 React를 쓰니, 컴포넌트 패키지 하나로 웹과 앱을 다 커버하면 좋겠다고요. 그런데 기존 웹에서 쓰던 shadcn/ui 쪽을 다시 보니, 웹에서만 자연스러운 로직이 상당히 많이 들어가 있었습니다. DOM 이벤트, 포커스 트랩, Radix 포털, asChild같은 패턴이요. 그대로 RN에 끌고 가기엔 “공유”보다 “예외 분기”가 먼저 쌓일 것 같았습니다.
그래서 역할을 이렇게 나눴습니다.
@chulgang/ui : 웹과 어드민용. shadcn/ui 계열로, Radix primitive와 Tailwind(DOM)로 이루어져 있습니다.@chulgang/ui-native : 모바일(Expo)용. React Native Reusables 계열로, rn-primitives와 NativeWind로 이루어져 있습니다.@chulgang/tokens : ui와 ui-native가 함께 쓰는 색,타이포,간격의 이름표입니다. colors / typography / spacing, 그리고 theme CSS 진입점이 여기에 있습니다.
구현체는 둘로 두되, 부르는 이름은 맞추려 했습니다.
예를 들면, @chulgang/ui/button, @chulgang/ui-native/button 이렇게 되었습니다.



그리고 실제로 구현된 모습을 보면, 다음처럼 구현되어 있습니다.

지금은 ui/button과 ui-native/button이 함께 있기 때문에 as NativeButton으로 되어있지만, 실제 코드로 보면 둘다 <Button>으로 동일하게 사용합니다.
지금 단계까지는 여기까지 왔습니다. 저는 추후에 각 버튼에서 사용하는 button variant도 패키지화를 시켜야 할지 고민하고 있습니다. 다만 컴포넌트가 분리되어있는데, 스타일만 통일해야 할까?라는 고민이 있어서, 지금은 그냥 두고 있습니다.
기술 스택을 선정하고 패키지를 만든 뒤에, 드디어 화면을 만들기 시작했습니다. 다만 앱 전체를 한번에 만들기 보다는 화면 단위로 하나씩 만들기로 결정하고 메인 페이지부터 만들기 시작했습니다.
당연히 AI 에이전트를 시켜서 만들었고, 다음과 같이 진행했습니다.
이게 계속 반복되다가, 반복이면 스킬로 만들어 알아서 돌려야겠다는 생각이 들었는데요. 그 결과가 mobile-design-sync 입니다.
한 줄로 이 스킬을 설명하면, Figma 링크 하나로 모바일 웹을 먼저 맞추고 그 다음 앱을 맞추며, 결과를 스크린샷으로 남기는 end-to-end 워크플로입니다. 사람이 매 슬라이드마다 추가적인 명령과 컨텍스트를 전달하지 않아도 되게 스킬을 만든 것입니다.

이 스킬이 실행되면 다음처럼 워크플로가 진행됩니다.
다음은 실제 정리된 마크다운 문서를 공유하면서 결과를 살펴보겠습니다.





저는 특히 2단계에서 큰 희열을 느꼈습니다. 앱 이전에는 단순히 피그마 전체 스크린샷을 주고, 만들때 AI가 초벌로 만들어준 작업이고, 앱 이후가 해당 스킬을 통해 싱크한 결과물입니다.
실제로 보면 피그마와 최종 결과물이 약간 다른 부분이 있는데요. 이게 중간 피그마 업데이트가 되지 않아, 모바일 웹이 최신 결과물이고 피그마가 Outdated된 파일이기 때문입니다. 하지만 말씀드렸다시피 웹이 SSOT(Single Source of Truth)이기 때문에, 모바일 웹을 기준으로 앱을 만든 것을 확인할 수 있습니다.
이렇게 스킬을 만들고 개발자는 최종 마크다운으로 결과만 확인 후, PR을 Merge하는 반복적이지만 지루한 과정의 연속이었습니다. 그 결과 크게는 3일 동안 어마무시한 라인을 수정하면서 완성하게 되었습니다.


또 AI 에이전트를 사용하면서 처음으로 모든 토큰을 리셋된지 3일 만에 전부 다 쓰게 되었습니다. 저는 결제일이 7일인데, 11일날 토큰을 전부 다 사용했다는 알림이 오더라고요. 그런데도 계속 가능했던 이유는 커서 또한 다 쓰게 되면 100불짜리 추가 크레딧을 주기 때문입니다.
그럼 최종 결과는 어떻게 되었을까요? 앱 출시까지 바로 완료했을까요? 아쉽게도 결론적으로는 실패했습니다.
그 이유는 크게 3가지였습니다.
여기에 각 픽셀이나 토큰 단위의 싱크도 추가로 필요했고, 데스크탑 웹과 모바일 웹의 반응형 디자인의 차이까지 생각보다 여러 추가 수정사항이 계속해서 나왔던 탓입니다. 이번 편에서는 여기까지로 마무리짓고, 다음 편에서는 이러한 역경을 이겨낸 최종 출시까지의 여정을 다뤄보겠습니다. “앱 출시까지 2주면 된다”를 실제로 테스트해 본 최종 후기로 돌아올게요.
현재 FDE로 일하시거나, 최근 1년 내 일하셨던 분들은
“국내 FDE 현황 조사 2026” 참여하고, 리포트 & 네이버페이 포인트 받아가세요!
ⓒ요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.