MJS
안녕하세요!
문재석입니다. 👋
국내 최초 라이브 커머스 Grip에서 모바일 웹, 웹뷰, 그리고 백오피스 등 다양한 프로덕트를 만들며 좋은 사용자 경험이 곧 매출로 이어지는 경험을 했습니다. 팀이 함께 쓰는 코드를 중요하게 생각하고, 문제를 해결할 때는 원인 분석부터 해결까지의 과정을 규칙으로 만들어 그 규칙이 지켜지는지 자동으로 검증되게 하는 방식을 선호합니다.

Work Experience

그립컴퍼니

2022.08 - 재직 중
프론트엔드 개발자
- 프론트엔드팀 (2022.08 - 2022.12) → US TF · Media FST 겸직 (2023.01 - 2024.06) → 프론트엔드팀 (2024.07 - 2025.12) → 커머스개발팀 (2026.01 - 현재)- 팀 전체가 프로덕트 전반에 사용할 수 있는 패키지 모노레포를 설계하고, 패키지 릴리스부터 프로덕트별 자동 업데이트까지의 파이프라인을 구축 (패키지 4개 생성)- 입사 당시 3명이었던 팀원이 10명으로 늘어나고 바뀌는 동안 코드 컨벤션·브랜치 전략·CI/CD를 수립해 문서화- 코드 컨벤션을 통일하기 위해 AI 하네스 엔지니어링을 학습하고 팀에 적용- 고연차 중심으로 구성된 목적 조직(US TF · Media FST, 2023 - 2024)에 동일 연차 중 유일하게 투입됐던 경험을 바탕으로 현재까지 프론트엔드 파트의 주축을 담당

Skills

TypeScript
React
Next.js
Tailwind CSS
Zustand
TanStack Query
Sass
HLS.js
Firebase
Turborepo
Google Analytics
GitHub Actions
Jenkins
Git
GitHub
Case Studies

깊게 본 문제

무엇을 했는지보다 왜 그렇게 했는지를 남깁니다.

Tailwind important/plain 듀얼 빌드

문제
Chakra UI를 사용하고 있던 프로덕트들에 Tailwind CSS 기반으로 만든 gds-ui(디자인 시스템 기반 컴포넌트 패키지)를 적용했을 때 우선순위 문제가 발생해 이미 운영 중인 서비스의 사용성 및 외형에 영향이 있었습니다. 따라서 마이그레이션이 진행되지 않은 프로덕트에선 gds-ui가 우선순위를 가질 수 있도록 !important가 필요했고 진행된 프로덕트에선 필요하지 않았는데, 이는 새로 작성하는 코드의 className 스타일링을 방해하기도 했습니다.
선택
이를 해결하기 위해 빌드 두 가지로 나눴습니다. 우선 소스에서 '!'를 전부 제거하고, 빌드 타임에 Babel 플러그인이 cva·cn·className 안의 클래스에만 '!'를 붙인 important dist와 붙이지 않은 plain dist 두 벌을 만들도록 했습니다. 최종적으로 plain·important·baseline 3중 컴파일 결과를 대조하는 정합성 검증을 빌드에 붙여 '!' 변환의 문제를 매 빌드마다 확인합니다.
결과
패키지 하위 버전만 사용할 수 있었던 마이그레이션이 완료되지 않은 프로덕트에서도 패키지 상위 버전을 문제 없이 사용할 수 있었고 안전한 마이그레이션이 가능했습니다.

빈 화면을 줄이는 데이터 분리와 ISR 개편

문제
Next.js로 전환하며 서버 컴포넌트로 초기 화면을 먼저 그리려 했지만, 서비스 대부분이 개인화된 화면이었습니다. 개인화 데이터가 서버와 클라이언트 컴포넌트 사이에서 달라지면 화면이 깨지고, 인증 로직이 전 페이지에 걸려 있어 ISR은 아예 쓸 수 없는 구조였습니다.
선택
서버 개발자와 협의를 통해 공통 데이터와 개인화 데이터를 분리하기로 했습니다. middleware + context + singleton 인증 로직으로 초기 데이터는 서버에서 그리고 나머지는 skeleton이 채우게 했습니다. 이후 인증이 필요한 영역과 정적으로 제공 가능한 영역을 나누어 ISR을 적용할 수 있는 구조로 개편했습니다.
결과
어떤 화면을 서버에서 그리고 어떤 화면에 skeleton을 넣을지 판단하는 기준이 생겼고, 그 기준이 폴더 구조와 컨벤션으로 이어졌습니다. ISR 적용 페이지의 트래픽 처리량은 인프라팀 측정 기준 약 10배 증가했습니다.

음소거 해제 상태의 자동 재생

문제
브라우저 정책으로 인해 서비스 초기부터 모바일과 PC 브라우저에서 소리가 켜진 채로 자동 재생이 불가했습니다.
선택
정책상 사용자가 이미 상호작용한 페이지에서는 재생을 허용한다는 점, 그리고 SPA는 HTML이 하나라서 라우팅을 하더라도 같은 페이지로 인식할 수 있다는 점에 주목했습니다. 최상위 layout에 video 요소 하나를 두고 방송·쇼츠 페이지에 진입하면 영상 출력을 위한 계층으로 이동시키고 페이지에서 이탈하면 위치를 되돌리는 구조로 바꿨습니다.
결과
iOS, Android, PC의 주요 브라우저에서 소리가 켜진 채로 자동 재생이 가능해졌습니다. 영상을 상하로 스와이프하여 이동할 때 라우팅이 발생하더라도 연속 시청이 가능해졌고, 이때 플레이어를 React Player에서 HLS.js로 이관하면서 번들 약 35% 감소, Lighthouse Performance 20% 향상이 뒤따랐습니다.

늘어나고 반복되는 웹뷰 페이지

문제
앱 내 웹뷰가 늘면서 화면마다 레이아웃 및 외형, 그리고 통신 규격 등에 차이가 발생하였습니다. 이 상태로는 본래 백엔드에서 관리하던 페이지를 프론트엔드로 옮길수록 차이가 점점 커질 상황이었습니다.
선택
우선 공통 레이어를 먼저 만들었습니다. Message event 기반 규격(call-client)을 iOS·Android와 협의해 만들고, safe-area·pull to refresh·하드웨어 백키 같은 앱 고유 동작은 event bus와 hook으로 추상화했습니다. 구버전 앱은 앱 버전 분기로 호환성을 유지하고, 서버 페이지와 프론트엔드 페이지는 feature flag와 redirect로 서로 전환할 수 있게 했습니다.
결과
장바구니, 쿠폰, 주문서, 방송 통계·회원등급, 상품 옵션, 주문내역 등 다수의 페이지들을 같은 방식으로 이관할 수 있었으며 장애가 나면 배포 없이 서버 페이지로 돌리거나 기능을 숨길 수 있어 이관마다 롤백 계획도 통일되었습니다.

AI 코딩 에이전트에게 맡길 것과 맡기지 않을 것

문제
기술 스택 마이그레이션이나 페이지 이관처럼 유사한 작업을 반복하는 상황이 늘었습니다. 유사한 작업임에도 불구하고 개인마다 판단이 다르기 때문에 각자의 기준을 따르게 될 경우 결과가 달라지는 문제가 있었습니다. 심지어 AI를 사용하더라도 각자의 AI가 다른 판단을 내리는 것이 일반적이었습니다.
선택
기준을 레포에 문서로 남기고 에이전트가 읽게 했습니다. 규칙에는 항상 실제 사고 사례와 자동 검증 스크립트를 짝지었습니다. 규칙만 있으면 지켜지지 않고, 검증만 있으면 왜 그런지 알 수 없기 때문입니다. 에이전트가 레포의 기존 코드를 복사해 이미 고친 규칙 위반을 다시 만들어내는 것을 보고 '기존 코드가 규칙과 다르면 규칙이 진실'을 최상위 규칙으로 명시했습니다. 개발자가 직접 읽고 승인하지 않은 커밋, 편의를 위한 로컬 패치, 개발자가 검증하지 않은 화면은 반드시 개발자가 개입하도록 커맨드·메모리·권한 허용 목록 세 층에 같은 경계를 두었습니다.
결과
개인적으로 기준을 만들고 검증을 마친 뒤 팀 전체에 이를 도입했습니다. 프론트엔드 4개 레포에 적용된 뒤 팀원들 간의 협의를 통해 보완해 나갔고 서로의 AI를 검증하는 단계까지 확산됐습니다. 이 중 제가 도입했던 레거시 페이지를 분석하여 비개발자용 기능명세·PRD·가시화 HTML을 생성하는 커맨드는 기획/디자인/QA에서 최소 한 달 걸리던 분석 기간을 최대 1주일로 단축했습니다.
Timeline

꾸준히 개발합니다

주요 개발 이력들을 시간순으로 정리했습니다. 새로운 것도, 오래된 것도, 모두 판단이 쌓인 기록입니다.

  • 품절 상품 재입고 알림 신청

    Grip

    - 품절 상품에 재입고 알림을 신청하고 MY 탭에서 신청 내역을 확인하는 기능 개발 (진행 중)- 장바구니 내 품절 상품에서도 신청 가능하도록 동선 추가, 네이티브 연동 및 클라이언트 로그 설계
  • 주문내역 페이지 이관

    Grip

    - 백엔드가 렌더링하던 주문내역과 주문 상세, 취소/교환/반품 상세 페이지를 프론트엔드로 전환 (진행 중)- 구버전 코드를 분석해 기능명세·PRD·가시화 HTML을 생성하는 커맨드로 분석 단계를 단축
  • G

    Grip Studio 상품 옵션 관리 고도화

    Grip Studio

    - Grip Studio(실시간 방송 시스템)에서 옵션이 많은 셀러가 옵션 기능을 쓰지 못한다는 VOC로 시작. 조합별 가격·재고의 인라인·일괄 수정과 등록 후 옵션명·옵션값 수정을 지원- 옵션 상품에 라이브가와 옵션가 범위를 함께 노출하고, 판매 가능·주문·점유 수량을 비즈니스 센터 연동값으로 표기
  • C

    Chakra UI → Tailwind 마이그레이션

    Grip Business, Grip Admin 2.0

    - CSS-in-JS 기반 Chakra UI v2는 Next.js App Router의 서버 컴포넌트와 맞지 않았고 디자인 시스템을 적용하기에도 적합하지 않아, 팀 내 기술 검토를 거쳐 일괄 전환- 운영 중인 비즈니스 센터와 어드민 두 프로덕트의 스타일링 스택을 서비스 중단 없이 교체- 런타임 비용으로 규모가 커질수록 로컬 속도가 저하되고 개발 환경 배포에 10분 이상 걸리던 문제가 있었고, 전환 후 개발 환경 배포 시간이 50% 감소- 코드를 건드리기 전에 마이그레이션 구조 설계를 별도 과제로 분리해 이관 방식, 토큰 대응, 두 스타일의 공존 전략을 먼저 확정- 이관 규칙을 문서와 하네스로 작성해 팀 전체가 같은 기준으로 화면을 이관
  • 그립페이 도입 (사내 간편결제)

    Grip

    - 인증·약관·쿠폰·주문서·네이티브가 모두 얽힌 결제 흐름을 새로 만들며 프론트엔드 전 구간 담당 (현재 QA 진행 중)- 그립페이 결제수단 영역 신설, 카드·계좌별 할부 가능 여부 분기, 현금영수증 처리, 그립페이 가입·결제수단 추가- 기존 페이지 이동 결제는 취소 시 쿠폰·포인트·주문 정보가 유실되는 경우가 많아 새 창 결제로 전환해 주문서를 유지- 새 창 방식으로 중복 API 통신과 중복 로깅을 차단- 결제 동선 중간 이탈 시 주문이 실패로 남던 케이스 개선- 앱 네이티브 결제 모듈과 웹뷰 간 연동 구조 수립- feature flag와 앱 버전 판별로 노출을 제어하며 단계적 배포. 사내 운영 테스트와 하위 버전 대응이 가능하고, 장애 시 배포 없이 즉시 차단
  • 상품 옵션 UI 이관 및 개선

    Grip

    - 서버 페이지였던 상품 옵션 UI를 프론트엔드로 이관하고 클라이언트 로그 추가- 라이브 구매 옵션 선택을 드롭다운에서 칩으로 바꾸고 구매 동선 UI를 통합
  • 프론트엔드 공용 패키지 모노레포 재구축 · GDS(Grip Design System)

    공용 패키지 (전 프로덕트)

    - 린터 설정만 있는 채 7개월간 방치되어 있던 레포를 프론트엔드의 모든 프로덕트가 의존하는 Turborepo + Changesets 기반 패키지 모노레포로 재구축- 전체 커밋의 51%, PR의 63% 작성 (2026.09 기준). 4개월 단독 운영 후 팀원 합류- gds-ui(디자인 시스템 컴포넌트)·gds-icons·overlay-system(선언형 모달)·frontend-git-hooks(CI/CD) 패키지 기획·구현- 디자인팀과 Figma Variables를 디자인 토큰의 단일 소스로 합의하고 Figma JSON을 CSS 커스텀 프로퍼티로 자동 생성하는 파이프라인 구축. 삭제·리네임된 토큰을 참조하는 컴포넌트가 있으면 빌드가 실패하는 검증 추가- important/plain 듀얼 dist와 dist 외부화 검증 가드 도입- 아이콘 222종을 Figma에서 SVGR로 자동 생성·동기화- 브랜치 확인부터 GitHub Packages 배포, 프로덕트 레포 bump PR, Slack 알림까지 릴리스 8단계를 명령 한 번으로 묶은 스크립트 작성- 디자이너가 완료 항목을 스레드로 올리면 프론트엔드가 티켓을 만들어 연결하고 스프레드시트로 디자인·개발 진행 상태를 공유하는 GDS 도입 프로세스 수립
  • A

    AI 코딩 에이전트 팀 내 도입

    Grip, Grip Business, Grip Admin 2.0, 공용 패키지

    - 프론트엔드 4개 레포에 에이전트용 프로젝트 규칙과 워크플로우 커맨드를 한 달 안에 도입. 이후 팀원들이 함께 편집하고 디렉토리 범위 규칙을 스스로 추가하는 단계까지 확산- 규칙과 자동 검증을 쌍으로 관리하는 패턴과 '기존 코드가 규칙과 다르면 규칙이 진실' 원칙 정착- 승인 없는 커밋, 프로덕트 레포 직접 패치 등 맡기지 않을 것을 커맨드·메모리·권한 허용 목록 세 층에서 일관되게 설정- 레거시 페이지를 분석해 비개발자용 기능명세·PRD·가시화 HTML을 생성하는 슬래시 커맨드 제작. 기획/디자인/QA에서 최소 한 달 걸리던 분석 기간을 최대 1주일로 단축
  • 한정 판매 라이브·라이브 주문서

    Grip, Grip Business, Grip Admin 2.0

    - 한정 판매 라이브 판매 유형 신설과 한정 판매 추첨 게임 추가- 배송비 상품 자동 주문서 세팅, 비회원 주문 시나리오 개선, 방송별 라이브 주문서 마감시간 설정- 방송 게임 동일 상품 반복 사용, 스토어 판매 유형 방송 설정 개선, 쿠폰 사용 불가 셀러 설정(어드민)
  • 방송 통계·회원등급 페이지 이관

    Grip

    - 백엔드가 렌더링하던 방송하기 > 통계 페이지와 내 회원등급 페이지를 프론트엔드로 전환- feature flag로 서버 페이지와 프론트엔드 페이지 노출을 제어해 배포 없이 전환·롤백
  • 그리퍼 후원하기 (젬 후원·선물하기)

    Grip, Grip Business, Grip Admin 2.0

    - 오퍼월 광고 도입에서 출발한 프로젝트가 젬(인앱 후원 재화) 기반 그리퍼(방송 진행자) 후원으로 방향을 바꿈. 3개 프로덕트에 걸친 작업을 티켓으로 분해해 팀원과 나누고, 전체 166건 중 102건을 직접 구현- 방송 화면(선물상자·선물 애니메이션·후원 현황), MY 탭(젬·후원 포인트·선물 내역), 홈(후원 랭킹·후원 TOP 그리퍼) 개발- 비즈니스 센터 후원 관리·젬 환전 신청/내역·부가세 신고, 어드민 후원 관리·젬 대량 지급·환전 지급 내역과 후속 정산 기능 개발
  • 슈퍼셀러 방송 집계 대시보드

    Grip Admin 2.0, Grip Business

    - 슈퍼셀러 대회 1~4라운드에 맞춰 집계 기준이 바뀔 때마다 비즈니스 센터·어드민 대시보드를 개편- Firebase 연동으로 라운드별 집계를 실시간 반영
  • 코드 개편 · ISR/SSR 분리

    Grip

    - Next.js 15 버전으로 업그레이드- 인증 로직 때문에 ISR을 쓸 수 없던 구조에서 인증 영역과 정적 영역을 분리해 ISR을 적용할 수 있게 개편- ISR 페이지의 트래픽 처리량 인프라팀 측정 기준 약 10배 증가
  • 방송 페이지 2차 개편

    Grip

    - 디자인팀의 GDS(Grip Design System) 가이드를 적용해 방송 페이지 2차 개편- 키보드·마우스 상호작용 등 UX 개선
  • 본인인증 페이지 개발

    Grip

    - 백엔드가 렌더링하던 본인인증 페이지를 프론트엔드로 전환
  • 주문서 페이지 개발

    Grip

    - 백엔드가 렌더링하던 주문서 페이지를 프론트엔드로 전환 (세 번째 이관)- Form 유효성 검사, 에러 핸들링, 시각적 효과 추가로 UX 개선
  • 판매자 센터 종료 프로젝트

    Grip Business

    - 비즈니스 센터로의 완전한 전환을 위해 판매자 센터 내 기능을 비즈니스 센터로 이관- 그리퍼 인터뷰에서 나온 개선 희망 사항을 추가 개발
  • 바이럴 프로젝트

    Grip

    - 사용자의 공유를 유도하기 위해 방송/상품/프로필 공유 기능 고도화- 방송 공유 시 채팅 뱃지 지급, 상품/프로필 공유 시 쿠폰 지급 등을 통해 유저 유입 유도
  • 쿠폰 페이지 개발

    Grip

    - 백엔드가 렌더링하던 쿠폰 페이지를 프론트엔드로 전환 (두 번째 이관)
  • 장바구니 페이지 개발

    Grip

    - 백엔드가 렌더링하던 장바구니 페이지를 프론트엔드로 전환
  • 방송 페이지 1차 개편

    Grip

    - 앱에만 있던 기능을 웹에서도 제공해 웹과 앱의 경험 차이를 축소
  • 상품 등록 임시 저장 기능 추가

    Grip Business

    - 그리퍼가 비즈니스 센터에서 상품을 등록하다가 임시 저장 후 화면을 떠날 수 있는 기능 구현- 약 40개 필드의 저장·유효성 검사·불러오기 구현- 메뉴 이동, 뒤로 가기 등 화면 이탈 시도 시 confirm을 표시
  • 카카오스토리 내 Grip SDK 개발

    Grip, Grip Admin 2.0

    - 카카오스토리 앱 안에서 도는 Grip SDK(웹뷰)를 개발. 카카오스토리 개발자들과 협업해 앱의 세 번째 탭에 탑재- 웹뷰 내 구성 요소를 제어하는 어드민 페이지 개발
  • G

    Grip Business 출시

    Grip Business

    - 셀러와 그리퍼가 상품·방송·쿠폰·계약 등 자산 전반을 관리하는 비즈니스 센터를 개발해 출시하고 기존 판매자 센터의 점진적 종료를 시작- 디자인 시스템을 적용한 컴포넌트를 설계하고, 디자인 토큰 수립·컴포넌트 명칭 통일·소통 창구와 순서 정리를 위해 디자인팀과 협업- 유저 타입에 따른 메뉴 접근 권한을 제어하는 hook과 HOC 설계- 영상·이미지를 DnD로 업로드하고 순서를 바꾸며 썸네일로 미리보기하는 컴포넌트 구현, Storybook으로 컴포넌트 문서화
  • 셀러온보딩 PO 과제

    Grip, Grip Admin 2.0, Grip Business

    - 입점 안내 페이지 개편, 공유하기 강화, 첫 방송 미션 추가 등을 개발
  • G

    Grip 웹 재출시

    Grip

    - 레거시와 기술 부채가 쌓인 React SPA를 Next.js로 점진 전환해 재출시하고 PC·모바일·웹뷰 전 환경에 대응. 이후 page router → app router → v15까지 점진 업그레이드- 전환 과정의 middleware 인증 오류, 서버 컴포넌트 내 비즈니스 로직 오류, 컴포넌트 구조로 인한 중복 렌더링을 디버깅하고 구조적으로 해결- 공통 데이터와 개인화 데이터를 분리해 초기 화면을 서버에서 그리고 나머지는 skeleton이 채우는 구조 설계- 앱의 기능 및 디자인에 맞춰 UX 간극 축소
  • 게임 참여 기능 개발

    Grip

    - Firebase를 활용해 라이브 방송을 시청하는 중에 추첨, 경매, 선착순 게임에 참여하는 기능 개발- 복잡도 높은 애니메이션을 CSS로 직접 구현해 성능 저하 방지
  • G

    Grip Admin 2.0 출시

    Grip Admin 2.0

    - 백엔드에서 관리하던 사내 운영·기획 담당자용 어드민을 프론트엔드로 새로 개발해 출시하고 기존 어드민 1.0을 점진적으로 종료- React Hook Form과 Zod로 복잡한 Form의 유효성 검사와 제출을 관리- 정렬·편집·순서 변경 등이 포함된 복잡한 테이블과 검색 필터 구현. 필터를 스토리지와 쿼리 파라미터에 저장해 메뉴 이동·새로고침 후에도 결과 유지- Mock Service Worker 기반으로 API 의존 없이 개발 진행
  • 웹 플레이어 최적화

    Grip

    - 번들 크기를 줄이고 필요한 이벤트만 제어하기 위해 React Player 기반 플레이어를 HLS.js로 재구현하고 방송 페이지 전체를 리팩토링- 음소거 해제 자동 재생과 스와이프·스크롤·키보드 방향키 연속 시청 구조- Firestore collection과 doc에 중복 snapshot이 걸려 비용이 이중 청구되던 문제를 singleton과 context 기반 snapshot 관리로 차단- ID3 tag로 라이브 다시보기의 채팅·알림·후원 데이터를 재생 시점에 맞춰 출력. 용량이 큰 Lottie 파일은 CDN 캐싱 hook과 메모리 재사용으로 로딩 개선
  • G

    Grip Live (US) 출시

    Grip Live

    - Grip의 코어 기능만 추려 라이브 방송 시청·송출과 상품 판매가 가능한 US 전용 웹과 어드민을 약 3개월 만에 동시 출시- 서비스 전체를 iOS 및 Android 앱에 웹뷰로 연동, 글로벌 대응을 위한 i18n 적용- 서비스 종료 시점까지 유지 보수

Education

원티드 프리온보딩 프론트엔드 코스

2022.05 - 2022.06
수석 수료
- HR테크 기업 원티드에서 주관한 실전 프로젝트 중심형 코스- 총 5주의 기간 동안 12개 참가 기업이 제시한 과제를 수행하며 현업에서 요구하는 기술, 컨벤션, 커뮤니케이션 방식, 디자인 시스템 등을 학습- 최대 12년차 개발자들로부터 코드 리뷰를 받고 실무 팁·협업 노하우 강의를 이수

중앙대학교

2014.03 - 2022.02
경영학과 경영학 학사
Contact

연락을 환영합니다

대화를 나누고 싶으시거나 궁금한 점이 있으시면 언제든 dev.jaeseok@gmail.com으로 연락 주세요.

이 사이트는 Next.js 14와 Tailwind CSS로 만들어 Vercel에서 서비스하고 있습니다.