기술스택 선정 - 100-hours-a-week/KTB4-3rd-wiki GitHub Wiki

목차


1단계: 기술 검토 및 스택 선정

1. 언어

1.1 후보 비교

언어 장점 단점
JavaScript - 별도로 TypeScript를 공부하지 않아도 됨
- 타입 작성이 없어 초기 개발 속도가 빠름
- 타입 체크가 없어 런타임 오류가 발생할 수 있음
- 유지보수 시 데이터 구조 파악이 어려울 수 있음
- 변수명이나 데이터 구조 변경 시 누락 가능성이 있음
- API 응답 형태를 코드만 보고 파악하기 어려움
TypeScript - 데이터 타입을 명확하게 정의할 수 있음
- 컴파일 단계에서 오류를 발견할 수 있음
- 자동완성 기능으로 DX 향상
- 코드 수정 시 연관된 오류를 쉽게 파악할 수 있음
- 협업 시 함수와 변수의 용도를 파악하기 쉬움
- 초기 타입 작성에 시간이 걸림
- 러닝커브가 있음
- 프로젝트 설정과 빌드 과정이 복잡해질 수 있음
- 타입 오류로 개발이 중단될 수 있음

1.2 선택

  • TypeScript

1.3 선택 이유

  • TypeScript 사용 경험이 있어 러닝커브가 크지 않다.
  • TypeScript의 장점이 단점보다 크다고 판단했다.
  • 버전 업그레이드 과정에서 API 응답 형식 등이 변경되는 상황에 보다 안전하게 대응할 수 있다.
  • 데이터 타입을 명확하게 정의하여 예상하지 못한 런타임 타입 오류를 최소화할 수 있다.

2. React vs Vue vs Angular

2.1 특징 비교

기술 특징
React - TypeScript와 호환성이 좋음
- React Native를 사용하여 모바일까지 확장 가능
- 단방향 데이터 흐름으로 상태 예측이 쉬움
Vue - 양방향 바인딩 지원
- React의 VDOM 채택
- HTML을 그대로 사용할 수 있어 러닝커브가 낮음
Angular - 프레임워크가 무거워 초기 로딩 속도는 느린 편
- 페이지 전환 속도는 빠른 편
- 양방향 바인딩 지원
- 정해진 템플릿 문법 사용
- 세 기술 중 러닝커브가 가장 높음

세 기술 모두 컴포넌트 기반 UI 구성을 지원한다.

2.2 선택

  • React

2.3 선택 이유

기준 선택 이유
단방향 데이터 흐름 단방향 데이터 흐름 구조를 기본으로 하기때문에 데이터 흐름을 예측하기 쉽다.
TypeScript 호환성 JavaScript 기반 구조이기 때문에 TypeScript와 호환성이 좋다.
VDOM 이전과 변경된 부분만 실제 DOM에 반영하며, 개발자가 DOM을 직접 조작하지 않아도 된다.
러닝커브 React 사용 경험이 많기 때문에 익숙하고 빠르게 개발할 수 있다.
생태계 참고 문서와 예제가 많아 빠르게 개발해야 하는 환경에 적합하다.

참고 자료

image

3. 프레임워크

3.1 후보 비교

프레임워크 장점 단점 결정
Gatsby 정적 사이트 생성에 적합 정적 사이트 생성만 지원하여 지도, 채팅 등 동적인 페이지가 많은 서비스에는 적합하지 않음 제외
Next.js - CSR, SSR, SSG, ISR 등 렌더링 방식 선택 가능
- SEO에 유리함
- 라우팅, 이미지 최적화, 코드 분할 등이 통합됨
- 생태계와 자료가 풍부함
- Server Component, 캐싱, 렌더링 방식 등 학습할 내용이 많음
- 단순 SPA보다 구조가 복잡함
- 잘못된 렌더링 방식 선택으로 성능 저하가 발생할 수 있음
선택
Remix - 서버 중심 데이터 처리와 폼 제출에 강함
- 중첩 라우팅과 에러 처리 구조가 체계적임
- 웹 표준과 점진적 향상에 유리함
- 동적인 서비스와 데이터 변경 흐름에 적합함
- Next.js보다 국내 자료와 사용 사례가 적을 수 있음
- Remix만의 라우팅과 데이터 로딩 방식을 학습해야 함
제외
React + Vite - 구조가 단순함
- 개발 속도가 빠름
- SPA와 실시간 지도·매칭 UI 구현에 적합함
- 정적 파일로 배포하기 쉬움
- SSR, SSG, 라우팅, SEO 등을 별도로 구성해야 함
- 초기 HTML 기반 SEO에 불리할 수 있음
제외

3.2 선택 이유

기준 선택 이유
SEO 최적화 매칭과 커뮤니티 구조의 서비스이므로 사용자 유입이 중요하다. SEO 최적화를 통해 서비스 노출과 사용자 유입을 높일 수 있다.
유연한 렌더링 방식 지도나 채팅처럼 동적이고 사용자별 데이터가 다른 페이지는 CSR로, 커뮤니티 게시글처럼 정적인 데이터는 SSR로 구현할 수 있다.
통합 기능 파일 기반 라우팅, next/image 이미지 최적화, 라우트 단위 코드 분할 등을 기본으로 제공하여 설정 부담을 줄일 수 있다.
번들사이즈 축소 서버 컴포넌트는 클라이언트 번들에 포함되지 않아 번들 사이즈 축소에 유리하다.

3.3 어떻게 사용할것인가

  • 서버컴포넌트와 클라이언트 컴포넌트를 나눠 하이브리드 렌더링 방식으로 진행할 것 같다.
  • 기본적으로 서버컴포넌트를 사용하고, 사용자 상호작용이나 브라우저 api가 필요한 곳은 클라이언트 컴포넌트를 사용 할 예정.
  • 클라이언트 컴포넌트의 범위를 최소화하여 hydration 시간을 단축해 FCP와 TTL의 간격을 줄이도록 할 예정.
  • 커뮤니티 게시글처럼 꼭 실시간 데이터가 필요하지 않은것들은 Ondemand ISR 방식을 사용해도 괜찮을 것 같다.

Ondemand ISR : 캐시된 정적 페이지를 제공하다가 해당 데이터 변경이 일어나면 관련 캐시를 무효화하고 이후 요청부터는 변경된 데이터로 제공하는 방식

공식문서 - 서버,클라이언트 컴포넌트

공식문서 - on-demand-revalidation-with-revalidatepath

공식문서 - revalidatePath


4. 기타 라이브러리

4.1 UI 라이브러리

라이브러리 장점 단점 결정
Base UI - 접근성, 키보드 조작, 상태 관리 등 기본 동작 제공
- 기본 스타일이 없어 자유롭게 커스터마이징 가능
- Tailwind CSS, CSS Modules, 일반 CSS 등과 함께 사용 가능
- 지속적인 업데이트와 유지보수
- 기본 스타일을 직접 구현해야 함
- 디자인 토큰과 컴포넌트 규칙을 별도로 정해야 함
- 빠른 화면 구성에는 시간이 오래 걸릴 수 있음
- 프로젝트 규모가 커지면 자체 디자인 시스템 관리 필요
일부 사용
Material UI 기본적인 UI 컴포넌트를 빠르게 구성 가능 Material Design 기반이므로 자체 디자인을 적용하려면 많은 커스터마이징이 필요함 제외
직접 구현 - 프로젝트 디자인과 브랜드에 맞게 제한 없이 구현 가능
- 서비스 특화 UI를 원하는 방식으로 설계 가능
- 외부 라이브러리 의존성 및 버전 충돌 회피
- 컴포넌트 구조와 동작을 완전히 제어 가능
- 초기 개발 시간 증가
- 접근성, 반응형, 터치 동작, 애니메이션 등을 직접 처리해야 함
- 상태와 예외 상황을 직접 설계하고 테스트해야 함
- 자체 디자인 시스템 관리 필요
일부 사용

선택

  • Base ui사용 또는 직접 구현하기

UI 라이브러리 선택 이유

  • 기본 스타일이 없어서 자유롭게 tailwind를 사용해서 커스텀이 가능하다.
  • 제공되는 컴포넌트 종류가 충분하다고 판단하였다.
  • 접근성, 키보드 조작, 상태 관리 등 기본 동작을 제공해줘 효율적으로 개발이 가능하다
  • 지속적인 업데이트와 유지보수가 이루어진다.
  • shadcn이 radix대신 baseui를 기본값으로 전환

4.2 아이콘

라이브러리 장점 단점
lucide - 1600+개의 아이콘
- figma 플러그인
라이브러리 의존성 생김

선택

  • lucide Icon 라이브러리를 사용
  • 라이브러리에 없는 아이콘은 직접 svg 따와서 사용하는것으로 보완

선택 이유

  • 페이지 구현에 필요한 아이콘이 모두 제공되어있다.
  • figma 플러그인이 있어서 화면과 통일성이 좋다

4.3 스타일링

기술 장점 단점 결정
Tailwind CSS - 유틸리티 클래스를 조합해 빠른 UI 구현 가능
- 반응형, hover, focus 등 상태별 스타일 적용이 쉬움
- 디자인 토큰과 간격 체계 유지에 유리
- 사용한 스타일만 빌드에 포함
- 별도 CSS 파일 작성 부담 감소
- JSX의 className이 길어질 수 있음
- Tailwind 문법 학습 필요
- 동적 클래스 사용 시 빌드 과정에서 인식되지 않을 수 있음
결정
CSS / SCSS - 표준 CSS 기반이라 학습 부담이 적음
- 스타일을 세밀하게 제어 가능
- SCSS의 변수, 중첩, mixin 사용 가능
- 특정 라이브러리 의존성이 낮음
- 전역 스타일로 인한 클래스명 충돌 가능
- 프로젝트 규모가 커질수록 스타일 관리가 복잡해짐
- 반응형, 상태별 스타일, 디자인 토큰을 직접 관리해야 함
- CSS 번들이 커질 수 있음
제외
CSS Modules - 클래스명을 컴포넌트 단위로 지역 범위화
- 클래스명 충돌 감소
- 컴포넌트와 스타일을 함께 관리하기 쉬움
- CSS와 SCSS 모두 사용 가능
- 클래스 조합과 상태별 스타일을 직접 관리해야 함
- 조건부 스타일 코드가 길어질 수 있음
- 디자인 토큰과 컴포넌트 규칙을 직접 정해야 함
- 유틸리티 클래스를 제공하지 않음
제외

선택

  • Tailwind CSS

선택 이유

  • Tailwind CSS는 다른 ui 라이브러리와 호환성이 좋다
  • jsx안에서 스타일 수정이 가능해 유지보수측면에서 좋다

4.4 클라이언트 상태 관리

라이브러리 장점 단점 결정
Zustand - 보일러플레이트가 적음
- 번들 사이즈가 작음
- 러닝커브가 낮음
- 사용 경험이 있음
- 생태계가 넓음
- 프로젝트 규모가 커지면 Store 구조를 직접 설계해야 함
- Middleware 추가 시 번들 크기가 증가할 수 있음
선택
Redux - 전역 상태를 하나의 Store에서 관리할 수 있어 상태의 출처가 명확
- 기능별 Slice로 Store를 나눌 수 있어 프로젝트 규모가 커져도 일관된 구조를 유지하기 쉬움
- Zustand에 비해 개념과 설정해야 할 코드가 많아 초기 러닝커브가 높음
- 작은 규모의 상태를 관리할 때에도 Store, Action, Reducer, Slice 등을 구성해야 하므로 과한 설계가 될 수 있음
- 새로고침 후 상태 유지를 위해서는 별도의 저장 로직이나 라이브러리 설정이 필요
제외
Recoil - Atom 단위로 상태를 세분화 가능
- React 컴포넌트와 자연스럽게 연결 가능
- 2025년 1월부터 저장소가 Archived 상태
- 최신 React와의 호환성 및 유지보수가 어려울 수 있음
제외
Jotai - Atom 단위의 간단한 상태 관리
- 필요한 Atom만 구독하여 불필요한 리렌더링 감소
- 기본 기능과 유틸리티가 분리됨
- Atom이 많아지면 상태 간 의존성 파악이 어려울 수 있음
- 대규모 프로젝트에서는 상태 구조를 별도로 설계해야 함
- 고급 기능 사용 시 추가 학습 필요
제외

선택

  • zustand

선택 이유

  • 매칭탭이나 커뮤니티 등 유저가 등록을 할때 여러 페이지에서 사용자 입력을 받는 경우가 많다. 이때 전역상태관리가 필요하다.
    • 예를 들어, 택시팟 매칭 등록에서 출발지/목적지를 선택할 때 첫 화면에서 지정한 출발지 값이 위치 검색 페이지의 출발지 인풋에 있어야한다.
    • 반대로 위치 검색 페이지에서 뒤로가기를 눌렀을 때도, 유저가 지정한 출발지 값의 상태에 맞게 지도 위치 및 값이 나타나야한다.
스크린샷 2026-09-03 오전 10 52 02
  • 로그인 유도 모달같은 전역 모달이나 api 요청 실패같은 전역 토스트 상태도 zustand를 통해 관리 가능하다.
  • Redux와 비교해 보일러플레이트 코드가 적고, 간단한 API로 상태를 관리할 수 있다.
  • 별도의 Provider나 reducer 없이 사용할 수 있어 러닝커브가 낮으며, 기존 사용 경험을 활용할 수 있다.
  • selector를 통해 필요한 상태만 구독해서 불필요한 리렌더링을 줄일 수 있다.
  • 여러 페이지에서 사용자 입력을 이어서 받는 흐름이 많기 때문에 persist 미들웨어를 활용할 수 있다.
  • jotai는 세밀한 상태관리의 필요성을 아직 느끼지 못해 제외.

4.5 서버 상태 관리

라이브러리 장점 단점 결정
TanStack Query - api 요청 상태관리
- 캐싱과 중복 요청 제거
- stale 데이터 관리
- 백그라운드 refetch
- 페이지네이션, 무한스크롤
- 낙관적 업데이트
- SSR hydration
- 기능이 많아 학습량이 있음
- 캐시 정책과 Query Key 설계 필요
- 런타임 및 캐시 관리 코드 추가
선택
SWR - API가 단순하고 사용하기 쉬움
- 자동 재검증과 캐싱 제공
- Tree-shaking과 Path import 지원
- 번들 및 런타임 부담이 비교적 적음
- TanStack Query보다 캐시와 Mutation 기능이 단순함
- 복잡한 서버 상태 흐름은 직접 구현해야 할 수 있음
제외

선택

TanStack Query

선택 이유

  • mutation이 자주 일어나고 서버간의 관계와 변경 흐름이 복잡함.
    • 예를 들어 유저가 채팅방에 입장하면, 다음 서버 상태들도 변경되어야합니다.
    • 바텀시트 목록의 참여인원 수 / 게시글 상세의 참여인원 수 / 유저의 채팅방 목록
    • TanStack Query는 query key의 계층 구조를 기반으로 특정 데이터만 무효화할 수 있기 때문에 이런 구조에 적합하다고 판단했습니다.
스크린샷 2026-09-03 오전 11 22 32 스크린샷 2026-09-03 오전 11 23 33 image

4.6 런타임 타입 검사

라이브러리 장점 단점 결정
Zod - TypeScript 타입과 런타임 데이터 검증을 함께 관리 가능
- API 응답과 Form 입력값 검증에 활용 가능
- TypeScript 타입 자동 추론 가능
- Zod Mini 사용 시 번들 크기 감소 가능
- 클라이언트 사용 시 검증 코드가 번들에 포함됨
- 복잡한 Schema가 많아지면 JavaScript 크기가 증가할 수 있음
선택

선택

Zod 사용

선택 이유

  • typescrip만으로는 런타임 데이터 검증을 수행할 수 없기 때문이다.

  • 서버가 잘못된 데이터를 보냈을때, 검증을 수행하지 못하면 예상하지 못한 에러나, 의도하지 않은 결과가 나올 수 있다.

  • 사용자 입력을 받을때도, zod를 통해 폼 검증 코드를 하나의 스키마에 모을 수 있습니다.

  • zod를 사용하지 않으면, 타입과 검증 규칙을 별도로 작성해야합니다. 이로 인해 타입과 검증 규칙이 서로 달라질 수 있는 위험이 있습니다.

  • 다만, 큰 데이터의 경우는 매번 검증하면 파싱 비용으로 성능 저하가 발생할 수 있기 떄문에, 다음 방법들을 고려하겠습니다.

    • API 응답을 처음 받는 경계에서 한 번만 검증하고 그 결과 재사용
    • 필요한 필드만 부분 검증
    • 서버 검증
    • 전용 validator 사용

4.7 Form

라이브러리 장점 단점 결정
React Hook Form - Form 상태 관리와 입력값 검증을 간단하게 처리 가능
- 작은 크기와 적은 의존성
- 불필요한 Form 전체 리렌더링 감소
- SEED UI와 연동하기 좋음
- 복잡한 Form에서는 추가 학습 필요
- Zod Resolver 사용 시 추가 JavaScript 포함
- Form 상태와 서버 상태를 별도로 관리해야 함
사용

선택

React Hook Form 사용

선택 이유

  • 직접 Form 검증 hook을 작성하지 않고도 간편하게 구현 가능하다.
  • 크기가 작아서 번들 부담도 적다
  • form의 불필요한 리렌더링을 막아준다.
  • 아래와같은 인풋을 여러개 받는 form 화면이 서비스에 꽤 많아서 활용도가 높다.
스크린샷 2026-09-03 오후 4 13 09 image image

4.8 컴포넌트 문서화

라이브러리 장점 단점 결정
Storybook - 컴포넌트를 페이지와 분리해 개발 및 테스트 가능
- 공통 컴포넌트의 상태와 Variant 문서화에 적합
- 디자이너와 개발자가 UI를 확인하기 쉬움
- Story 작성과 설정에 추가 시간 필요
- 의존성과 빌드 시간 증가
- 팀 규모가 작거나 컴포넌트가 적으면 활용도가 낮을 수 있음
- 실제 페이지와 Storybook 환경이 달라 별도 검증 필요
사용

결정

storybook 사용

결정 이유

  • 디자인시스템 관리가 용이하다.
  • 당근의 디자인시스템 Seed를 사용하긴해도 커스텀이나 자체 컴포넌트를 스토리북으로 관리하는게 장기적으로 유리할 것이라고 생각했다.
  • 컴포넌트를 따로 떼서 테스트할 수 있다는 점이 좋다고 생각했다.
  • 협업을 할때 스토리북 배포를 통해 컴포넌트 단위 피드백 및 커뮤니케이션을 할수있어서 좋았다.

4.9 최종 선택

사용처 선택한 라이브러리
UI Base UI
Icon lucide Icon 라이브러리
Style Tailwind CSS
클라이언트 상태 관리 zustand
서버 상태 관리 tanstack query
런타임 타입 검사 zod
Form react hook form
컴포넌트 문서화 storybook

5. 린터 및 포매터

  • oxlint
  • oxfmt

사용 이유

  • Oxlint는 ESLint보다 50~100배 빠르다고함 Oxlint 공식문서

  • typescript와 호환성이 좋음

  • 865개 이상의 규칙을 포함하고 있으며 , 대부분의 팀이 이미 사용하고 있는 린터 플러그인을 포괄하는 기능을 제공

  • Oxfmt는 Prettier보다 약 30배, Biome보다 약 2배 빠르다고함 Oxfmt 공식문서

  • Prettier의 JavaScript 및 TypeScript 적합성 테스트를 100% 통과


6. 외부 API

6.1 지도 API 후보

  • Naver Map
  • Kakao Map

기록

2026.09.02 pl미팅 피드백 기반 추가학습 2026.09.03 pl미팅 피드백 기반 추가학습 2026.09.04 pl미팅 피드백 기반 추가학습

⚠️ **GitHub.com Fallback** ⚠️