비바리퍼블리카 (토스)
2024.06 ~ 2026.06
Frontend UX Ops Engineer
UX Platform Tribe / Interaction Team
Interaction Team에서 디자이너의 모션 저작과 개발자 핸드오프를 돕는 도구, 여러 서비스가 함께 사용하는 컴포넌트·패키지를 개발했습니다. 토스쇼핑 결제 화면에도 직접 참여해 모션을 구현하고, 저사양 환경의 성능을 개선했습니다.
인터랙션 패키지 현대화
작업기록 ↗TDS Mobile과 여러 토스 서비스가 함께 쓰는 Interaction 패키지의 빌드 방식을 RSC 환경에 맞게 바꾸고, 패키지가 서비스에 요구하던 Emotion 의존성을 제거했습니다.
- -기존 tsc 빌드에 RSC 대응용 후처리를 덧붙이지 않고, 디자인플랫폼팀의 Vite 전환에 맞춰 Interaction 패키지 빌드를 옮겨
output.banner로"use client"를 일관되게 주입 - -Emotion 기반 구현과 peer dependency를 제거하고 대부분의 스타일을 inline style로 옮겨, 패키지가 소비 서비스에 Emotion을 요구하지 않도록 변경
- -Storybook에서 여러 인터랙션 컴포넌트 케이스를 확인한 뒤 새 메이저 버전으로 릴리즈하고, 변경된 지원 범위를 마이그레이션 문서로 안내
주요 의사결정
Emotion을 제거한 뒤 스타일링을 어떻게 제공할 것인가
Interaction 패키지는 TDS Mobile과 여러 토스 서비스가 함께 쓰는 공용 패키지였고, Emotion을 peer dependency로 요구했습니다. 그래서 Emotion을 직접 쓰지 않는 서비스도 이 패키지 때문에 Emotion을 함께 유지해야 했습니다. Emotion을 걷어낸 뒤 기존 스타일을 어디로 옮길지뿐 아니라, 그 선택이 또 다른 의존성을 서비스에 요구하지 않는지도 함께 봐야 했습니다.
새로운 의존성을 추가하지 않는 선에서는 여러 서비스가 이미 쓰고 있는 TDS의
vanilla-extract가 가장 자연스러운 후보였습니다. 다만 TDS 내부의 Interaction 패키지와 서비스가 직접 설치한 패키지의 버전이 달라질 수 있어, 빌드 설정과 버전 호환성까지 함께 맞춰야 했습니다. 다른 스타일 라이브러리는 새 의존성을 들일 만큼 얻는 이점이 크지 않았습니다. 패키지 안 컴포넌트들의 스타일을 검토해보니 별도 라이브러리가 필요할 정도로 복잡하지 않아inline style을 선택했습니다.inline style에서는 pseudo selector를 그대로 쓸 수 없어, 패키지 안에서 사용하던 대부분은 컴포넌트 구조를 바꿔 대체했습니다. 외부 코드 컴포넌트를 지원하기 위해 남아 있던 부분은 담당 팀과 논의한 끝에, 새 메이저 버전부터 해당 지원을 종료하기로 합의했습니다. Emotion 기반 구현과 peer dependency를 함께 걷어내, TDS와 Interaction 패키지를 직접 사용하는 서비스 모두 이 패키지 때문에 Emotion을 유지할 필요가 없도록 했습니다.- -기존 tsc 빌드에 RSC 대응용 후처리를 덧붙이지 않고, 디자인플랫폼팀의 Vite 전환에 맞춰 Interaction 패키지 빌드를 옮겨
데우스랠리 — 모션 저작·프리뷰·플랫폼별 코드 생성 도구
작업기록 ↗데우스랠리는 랠리 에디터에서 검증한 편집 방식을 모션 저작·실시간 프리뷰·Web/iOS/Android 코드 생성까지 확장한 도구입니다. 디자이너가 조정한 모션을 제품 개발자에게 코드로 전달할 수 있도록, 패널·타임라인·프리뷰·코드젠이 같은 편집 데이터를 기준으로 동작하게 만들었습니다.
- -모션·이징 패널, 타임라인의 duration/delay 편집, 멀티노드 선택을 구현하고, 수정한 모션을 바로 확인할 수 있는 실시간 PIP 프리뷰를 연결
- -타임라인에서 바뀐 값이 조작 패널, 프리뷰, 코드젠 입력까지 같은 기준으로 이어지도록 편집 상태 구조를 정리하고, 스크롤 트리거·커스텀 easing·신규 모션 속성 요구를 같은 흐름에 연결
- -노드별 motion/transition 데이터를 루트 기준 타임라인 데이터로 변환해 Web/iOS/Android 핸드오프 코드 생성 흐름을 구현하고, 데이터 변환·타임라인 계산·코드젠·주요 에디터 동작 회귀 테스트 구축
주요 의사결정
트리 구조에서 반복되는 수정 오류를 어떻게 줄일 것인가
데우스랠리에서는 중간 노드 하나를 수정할 때도 그 노드의 데이터만 보고 작업하기 어려웠습니다. Deus에서 받은 트리 구조를 그대로 사용하고 있어, 부모·형제·자식에 미치는 영향까지 함께 확인해야 했기 때문입니다. 여러 노드의 관계를 함께 고려하는 과정에서 타입 오류가 나거나 필요한 로직을 빠뜨리는 일이 반복됐습니다.
이 문제의 해결책으로 랠리 에디터에서 사용했던
flatTree구조로 바꾸자고 동료에게 제안했고, 실제로 적용해 함께 검증했습니다.flatTree에서는 현재 노드만 바꾸면 되므로, 관계를 따라 수정하다 생기던 타입 오류와 로직 누락도 줄일 수 있다고 기대했습니다. 원본 트리를 펼쳤다가 코드 생성 전에 다시 조립해야 했지만, 기능 추가와 수정이 단순해진다면 감수할 수 있는 비용이었습니다. 그러나 적용 뒤에도 동료가flatTree의 노드 관계를 이해하는 데 어려움을 겪었고, 팀이 기능을 추가하고 검증하는 과정의 복잡함도 줄지 않았습니다. 한 노드의 수정만 편해졌을 뿐 팀이 겪는 복잡함이 그대로라면, 처음 해결하려던 문제의 답이 될 수 없다고 판단했습니다.그래서
flatTree는 이 문제의 해결책이 아니라고 보고 Deus 원본과 같은 트리 구조로 돌아갔습니다. 그대로 복원하지는 않고, 각 노드 인스턴스가 자신과 관련된 계산과 변경 로직을 맡도록 메서드를 정의했습니다. 수정할 노드만 보면 됐던flatTree의 편의는 포기했지만, 변경에 필요한 로직을 각 인스턴스 안에서 다루면서 타입 오류와 로직 누락 가능성을 줄였습니다.토스쇼핑 결제 모션 — 클릭 직후 멈춤 개선
작업기록 ↗토스쇼핑 결제 플로우의 밀어서 결제와 바텀시트 전환 모션을 구현했습니다. 출시 후 운영 피드백에 따른 롤백과 재구현을 맡으며, 저사양 환경의 모션 성능과 브라우저 호환성을 함께 개선했습니다.
- -결제 버튼에서 바텀시트로 이어지는 전환과 기본·로딩 상태 모션을 구현하고, 스켈레톤 표시와 데이터 로드 시점에 따른 위치 변화 보정
- -Playwright와 CDP로 저사양 조건의 클릭 직후 멈춤을 반복 측정하고, 최종 구현에서 300ms 초과 멈춤이 재현되지 않음을 확인
- -Safari/WKWebView에서 그라디언트가 결제 핸들을 가리던 문제를 핸들에만
will-change: transform을 적용해 해결
주요 의사결정
클릭 직후 병목을 어떻게 풀 것인가
Rally로 밀어서 결제 모션을 완성한 뒤, 저사양 기기에서도 더 부드럽게 동작하도록 개선해달라는 요청을 받았습니다. 요청을 받고 바로 버튼을 누른 직후를 프로파일링해보니 모션에도 적지 않은 비용이 있었지만, 가장 긴 멈춤은 비즈니스 로직과 바텀시트 렌더링이 한꺼번에 실행될 때 생겼습니다.
연산량 자체를 줄이려면 비즈니스 로직을 건드리거나 모션을 단순화해야 했고, 둘 다 선택할 수 없었습니다. 그래서 클릭 직후 병목을 먼저 풀기로 했습니다. 한 시점에 렌더링이 몰리는 문제를 피하려고 바텀시트 상태 업데이트를
startTransition으로 처리했지만, Rally 타임라인의 모션이 정상적으로 재생되지 않았습니다. 각 모션을 분리하면 이 문제는 피할 수 있었지만, 관련 코드를 한곳에서 관리하려고 Rally를 쓴 이유도 사라졌습니다.바텀시트 상태 업데이트에
startTransition을 적용하려고 Rally 타임라인을 Framer Motion의 상태 중심 구조로 옮겼습니다. 타임라인에 모아두던 모션을 여러 상태로 나눠 관리해야 해 코드는 더 복잡해졌지만, 저사양 조건에서 반복 측정한 결과 클릭 직후 멈춤은 한 번도 300ms를 넘지 않았습니다.TDS 인터랙션 컴포넌트 — WebGL·CSS mask 시각 표현
작업기록 ↗토스 디자인 시스템에서 제품 코드와 디자인 도구 양쪽에 같은 시각 표현을 전달하기 위해 ProgressiveBlur와 EdgeShadow를 구현했습니다.
- -기본 CSS blur 필터로 표현할 수 없는 위치별 블러 강도 변화를 WebGL·framebuffer 기반 ProgressiveBlur로 구현하고, 에디터용 CSS fallback을 함께 구성
- -box-shadow로 재현하기 어려운 이미지 기반 그림자를 EdgeShadow 컴포넌트로 구현하고, maskImage와 radial-gradient를 조합해 가장자리와 코너 라운드의 음영을 처리
BenefitPoint — 강조 표현 React Native 컴포넌트
토스프라임 혜택 포인트 강조 표현을 제품 흐름 안에서 반복해 쓸 수 있도록 React Native 기반 BenefitPoint 4종 컴포넌트를 구현했습니다. React Native Text에 직접 마스킹을 적용하기 어려운 제약은 SvgText 렌더링과 영역 분리로 우회해, 인라인 텍스트·배지·래퍼·배너 문맥에서 같은 강조 표현을 제공했습니다.
Frontend Developer (UX) Assistant
UX Platform Tribe / Interaction Team
랠리 에디터
작업기록 ↗인터랙션 디자이너가 개발 가이드를 수기로 작성하던 과정을 타임라인 편집과 pseudo code 생성으로 바꾼 사내 에디터를 개발했습니다. 여러 모션과 중첩 타임라인을 편집하는 화면, flatTree 기반 데이터 인터페이스를 구현하고, 타임라인·조작 패널·설정창이 같은 편집 상태를 공유하도록 구성했습니다.
WikiText 컴포넌트
금융 용어의 뜻을 본문을 벗어나지 않고 확인할 수 있도록 WikiText 컴포넌트를 구현했습니다. 설명 데이터 처리와 공통 인터랙션 로직을 공용 모듈로 분리하고, 모바일·데스크톱용 컴포넌트에서 함께 사용하도록 구성했습니다.
Simplicity 디자인 컨퍼런스
참고 링크 ↗토스 디자인 컨퍼런스 Simplicity 웹사이트에서 모바일·데스크톱별 세션 탐색 화면과 전환 모션을 구현했습니다. 세션 간 스와이프와 카드·리스트 전환을 연결해 세션 목록을 둘러보고 다음 세션으로 이동할 수 있도록 구성했습니다.