AI가 UI를 뽑아낼 때, 개발자가 설계해야 할 세 가지

AI가 UI를 뽑아낼 때, 개발자가 설계해야 할 세 가지

스크린샷 한 장으로 React Native 앱이 생성되는 시대—컴포넌트 품질, 접근성, 상태 설계는 여전히 개발자의 몫이다.

AI UI 생성 React Native 자동화 접근성 설계 상태 관리 아키텍처 컴포넌트 품질 프로토타이핑 ARIA
광고

스크린샷 몇 장을 넣으면 동작하는 React Native 앱이 나온다. 공상이 아니다. dev.to에 공개된 오픈소스 프로젝트 ai-app-cloner는 Claude를 백본으로 삼아 iOS·Android 앱 스크린샷을 분석하고, 렌더링 결과를 원본과 비교하는 루프를 반복하며 픽셀 오차를 스스로 줄여나간다. 네비게이션 크롬을 읽어 탭 구조와 스택 푸시를 추론하고, Expo Router 설정까지 자동으로 생성한다. 단순히 '비슷하게 생긴 껍데기'가 아니라 태스크를 추가하면 저장되고, 앱을 껐다 켜도 데이터가 남는 수준의 결과물을 목표로 한다.

이 도구가 흥미로운 이유는 기술적 완성도보다 그것이 가리키는 방향에 있다. '프로토타입을 빠르게 만들어 사용자에게 보여주는' 흐름이 이제 스크린샷 수집 → AI 생성 → 헤드리스 테스트 자동화까지 하나의 파이프라인으로 연결된다. 검증 사이클이 극적으로 짧아지는 것이다. 그런데 바로 이 지점에서 질문이 생긴다. AI가 UI 코드를 쏟아낼 때, 개발자가 여전히 직접 설계해야 하는 것은 무엇인가?

첫 번째: 컴포넌트의 '뼈대'를 올바르게 고르는 판단

ai-app-cloner의 제작자가 솔직하게 인정한 한계 중 하나는 '조건부 플로우'다. 특정 상태에서만 진입하는 화면은 힌트 없이는 근사치로 처리된다. 이것은 단순한 기능 부재가 아니라, AI가 픽셀에서 의미를 추론하는 데 구조적 한계가 있음을 보여준다. 어떤 요소가 버튼인지, 그 버튼이 어떤 역할을 가지는지, AI는 시각적 패턴으로 추정할 뿐이다.

dev.to의 아코디언 컴포넌트 구현 가이드는 이 문제를 정면으로 건드린다. 가장 흔한 아코디언 버그는 <div>를 클릭 가능한 헤더로 쓰는 것이다. div는 포커스가 없고, 탭 순서에 들어가지 않으며, Enter·Space 키 이벤트를 받지 못하고, 보조 기술에 아무 정보도 전달하지 않는다. AI가 스크린샷을 보고 '눌릴 것 같은 영역'을 생성할 때, 그것이 <button>인지 <div>인지는 픽셀만으로는 구별할 수 없다. 올바른 HTML 요소를 선택하는 판단—그리고 그 판단이 만들어내는 키보드 접근성, 스크린 리더 호환성, 포커스 관리—은 여전히 개발자가 설계해야 하는 영역이다.

두 번째: 접근성은 AI가 대신할 수 없다

aria-expanded, aria-controls, role="region", aria-labelledby. 아코디언 하나를 제대로 만드는 데 필요한 ARIA 속성들이다. 이 속성들은 시각적으로 아무 차이가 없다. 스크린샷에 찍히지 않는다. AI가 이미지를 분석해 UI를 생성하는 방식으로는 원칙적으로 추론할 수 없다.

높이 애니메이션 하나도 마찬가지다. height: auto는 CSS 트랜지션의 대상이 될 수 없어서 패널이 그냥 팝업된다. max-height에 마법의 숫자를 쓰면 이상하게 이징되거나 콘텐츠가 잘린다. transform: scaleY는 텍스트를 찌그러뜨린다. 현대적인 해법은 CSS Grid의 grid-template-rows0fr에서 1fr로 트랜지션하는 것인데, fr 단위는 그리드 안에서 애니메이션 가능하기 때문에 콘텐츠 높이를 측정할 필요가 없다. 이런 트레이드오프는 시각적 결과물을 보고 역추론할 수 없다. prefers-reduced-motion 미디어 쿼리를 두 줄 추가하는 것도, 키보드 네비게이션에서 화살표 키로 헤더 간 포커스를 이동시키는 패턴도 마찬가지다. 접근성은 코드의 구조와 의도 안에 있고, 그 구조는 개발자가 설계해야 한다.

세 번째: 상태 설계는 UX의 뼈대다

Fintech 결제 흐름 구현 사례는 또 다른 차원의 문제를 보여준다. 만료되는 환율 Quote를 다루는 멀티스텝 플로우에서 개발자는 세 개의 문제를 동시에 풀어야 했다. 서버 상태와 앱 파생 상태를 어디에 둘 것인가, 카운트다운 타이머를 메모리 누수 없이 어떻게 구현할 것인가, 동적 폼 구조를 어떻게 재사용 가능하게 만들 것인가.

해법은 명확한 책임 분리에서 나왔다. TanStack Query는 서버에서 온 데이터(Quote 객체, 수수료, 라우트 설정)를 담당하고, Redux는 Quote 생성 시점에 한 번 파생된 만료 시각(quoteExpiresAt)과 카운트다운 초(quoteExpiryCountdownTime)를 전역 단일 진실의 원천으로 보관한다. 카운트다운 훅은 로컬 카운터를 줄이는 대신 절대 타임스탬프에서 매 틱마다 재계산해 브라우저 탭 스로틀링에 의한 드리프트를 자가 교정한다. clearInterval을 반드시 반환해 컴포넌트가 언마운트될 때 인터벌이 쌓이지 않도록 한다.

AI가 스크린샷에서 생성한 UI는 이 설계가 없다. 버튼이 눌리고 숫자가 바뀌는 것처럼 보이는 껍데기는 만들 수 있지만, 어떤 상태가 서버 소유이고 어떤 상태가 클라이언트 파생인지, 만료 검증을 언제 어느 레이어에서 수행할지, 렌더 성능을 위해 셀렉터를 어떻게 좁힐지는 픽셀 정보로 결정할 수 없다. 실제 Fintech 사례에서 "Quote 만료 시 어떻게 회복할 것인가"를 폼 작성 중에는 개입하지 않고 리뷰 단계와 최종 제출 직전에만 검증하기로 결정한 것은 사용자 맥락에 대한 이해에서 나온 판단이다.

AI와 개발자의 역할 재분배

ai-app-cloner가 스스로 인정한 한계는 솔직하다. 백엔드 없음, 브랜드 아이콘 근사, 캡처한 화면만 복제 가능. 이 한계들은 도구의 미성숙함이 아니라, AI가 시각적 패턴에서 추론할 수 있는 것과 코드의 의미적 구조에서만 설계할 수 있는 것 사이의 경계선을 드러낸다. 도구는 계속 강해질 것이다. SwiftUI와 Compose 지원, APK 디컴파일을 통한 정확한 값 추출이 로드맵에 있다.

그럼에도 개발자가 설계해야 할 세 가지는 분명해진다. 올바른 HTML 요소와 컴포넌트 구조를 선택하는 판단, 스크린샷에 찍히지 않는 접근성 속성과 인터랙션 패턴, 서버 상태와 클라이언트 파생 상태를 어떻게 분리하고 언제 검증할지에 대한 아키텍처 결정. AI는 프로토타입 생성 속도를 비약적으로 올려주지만, 이 세 층위의 설계는 여전히 개발자의 책임이다. 빠르게 만들어 검증하되, 프로덕션으로 가져가는 순간 이 세 가지를 다시 설계해야 한다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요