FE‐ 기술 스택 선정 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki

작성일자 : 2025.04.20


프로젝트의 목적

온기 : AI 기반 사진 자동 분류 기능을 제공하는 여행 기록용 웹 어플리케이션 서비스

프로젝트 요구사항

  • Visual 중심의 사용자 경험 (이미지 중심의 인터페이스, 지도)
  • SPA (페이지 이동 시 새로고침 없이 UX 향상)
  • 높은 수준의 사용자 상호작용 (앨범 커스터마이징, 보관함 수정/재분류 기능 등)
  • 데이터 일관성 유지 (공동 작업 환경에서 안정성 보장)
  • 복잡한 도메인 로직 처리

렌더링 전략
SEO 보다 사용자 경험이 더 중요한 서비스이다.
-> 클라이언트 사이드 렌더링 + 소셜 공유용 메타데이터 렌더링만 서버 처리 형태로 분리.


TypeScript

버전 TypeScript 5.8

JavaScript의 상위 집합으로 정적 타입 시스템을 도입한 언어.
정적 타입 시스템(컴파일 단계에서 변수의 타입을 결정)을 통해 안정성, 생산성, 유지보수성을 향상 시킬 수 있다.

Why TypeScript?

  • 프로젝트 확장성과 유지보수성 강화
    인터페이스 기반 설계 (시스템 컴포넌트 간 명확한 설계)
    제네릭 프로그래밍 (재사용 가능한 유틸리티 타입 생성)
    타입 추론을 통해 타입 안전성을 제공한다.

  • 개발 생산성 향상
    타입 검사 (컴파일 전 오류 발견)
    코드 자체가 문서 역할을 수행
    변경 사항이 미치는 영향을 즉시 확인 가능 (리팩토링 안전성)
    자동 완성 및 인텔리센스

  • API 통신의 타입 안전성 API 응답 타입 정의: 서버 응답 데이터 구조 명확화
    TanStack Query와 호환: 서버 상태 관리의 타입 안전성
    에러 처리 타입화: API 오류 상황에 대한 타입 안전한 핸들링

  • React 및 Next.js 호환성 컴포넌트 Props 타입 체크: 컴포넌트 간 데이터 전달 오류 방지
    훅 타입 추론: React 훅 사용 시 타입 안전성 제공
    Next.js 라우팅 타입 지원: 페이지 매개변수, 쿼리 문자열 등 타입 안전성
    상태 관리 라이브러리(Zustand) 타입 통합: 전역 상태에 대한 타입 안전성

In TypeScript 5.8

  • ECMAScript 모듈의 require()지원
  • 더 나은 타입 추론: 복잡한 타입 연산에서 정확도 향상
  • 최신 ECMAScript 기능 지원: 현대적인 JavaScript 기능 활용 가능
기술 스택 버전 호환성 이점
React ✓ (19.x) 컴포넌트 props 타입 체크, 훅 타입 추론 등
Next.js ✓ (15.x) 페이지 라우팅 타입 지원, API 라우트 타입 지원
Zustand ✓ (5.0.3) 상태 관리 타입 통합, 상태 변경 함수 타입 체크
TanStack Query ✓ (5.74.5) 쿼리 결과 타입 추론, mutation 타입 체크

React

버전 React.js 19

Why React?

  • 컴포넌트 기반 아키텍쳐
    컴포넌트를 독립적으로 구성하여 결합도를 낮추고 재사용성을 향상시킨다.

    • UI의 일관성을 유지할 수 있다.
      - 개발 효율성을 확보할 수 있다.
      Storybook, styled-components 등 다양한 컴포넌트 개발 도구들을 선택할 수 있다.
  • 단방향 데이터 흐름
    일반적으로 단방향 데이터 흐름은

    • 데이터의 흐름이 예측 가능하며 컴포넌트 간의 의존성이 명확하게 드러난다.
    • UI 업데이트가 예측 가능하고 일관되게 이루어지도록 보장한다.
    • 개발자가 코드를 이해하기 쉽게 만들고, 유지보수성이 높아진다.
    • 상태관리 라이브러리와 결합하여, 글로벌 상태 관리 시스템으로 쉽게 확장할 수 있다.

    공동 작업 시, 앨범 수정/재분류 등 사용자 상호작용 시
    단방향 데이터 흐름을 통해서 데이터 일관성을 유지하고 예측 가능한 상태 관리로 안정성을 확보한다.

  • Virtual DOM
    리액트의 가상 DOM과 조정 알고리즘(reconcilation)을 통해 효율적인 렌더링이 가능하다.

    • UI 업데이트에서 성능을 최적화 하여 사용자 경험을 향상 시킨다. (빈번한 대용량 이미지 및 지도 렌더링 등)
    • 실제 DOM 변경을 최소화 하여 부드러운 상호작용을 할 수 있다.
  • React Hook
    React 16.8이상 버전부터 Hook 기능을 제공
    함수형 컴포넌트 중심 설계에서도 상태와 생명주기 관리 기능을 사용할 수 있다.
    클래스 대신에 컴포넌트 내에서 로직을 처리할 수 있다.

  • CSR/SPA 구현 최적화
    선언적 패러다임으로 명확한 흐름으로 화면을 구성할 수 있다.
    독립적인 컴포넌트 단위로 코드 분할
    번들러와 결합하여 동적인 import와 지연 로딩으로 초기 로드 시간 단축

  • 확장성 및 지속 가능성
    React Native로의 확장
    대규모 커뮤니티 및 라이브러리

React 19 is now stable.

vite@latest 로 생성한 프로젝트 config 파일

// pakage.json
"dependencies": {
	"react": "^19.0.0",
	"react-dom": "^19.0.0"
},

In React 19

  • Action + new hooks
    Action : 비동기 전환을 사용하는 함수
    데이터 변경을 수행한 후 응답으로 상태를 업데이트
  • 서버 컴포넌트
    Next.js 서버 컴포넌트의 기반
  • 리소스 사전 로딩

세부 유틸리티 라이브러리

인증 관련

  • Kakao Oauth

이미지 관련

  • react-image-crop (react-easy-crop)
  • exif-js

지도/ 위치 관련

  • React Leaflet
  • Kakao Map

etc . . .

  • React DnD
  • Luxon

Next.js

버전 Next.js 15

Why Next.js?

  • Image 컴포넌트

    • 자동 이미지 최적화 (WebP 포맷 변환, 사이즈 조정)
    • 지연 로딩(Lazy loading)으로 초기 로드 시간 개선
      뷰포트에 들어올 때만 이미지를 우선적으로 로딩한다.
    • 레이아웃 시프트 방지
      이미지가 렌더링 되기 이전에 레이아웃을 확보함으로써 페이지 성능과 유저 경험을 향상시킨다.
  • 하이브리드 렌더링
    부분적 SSR (소셜 미디어 공유 페이지 메타데이터와 이미지 미리보기가 표시되지 않는 문제 해결)

  • Pre-Signed URL (S3) API 라우트 내장: 별도의 백엔드 서버 없이 /api 경로를 통해 서버리스 함수 형태로 백엔드 로직을 구현할 수 있다. 이는 pre-signed URL을 생성하는 데 적합하다. 보안성

    • Next.js의 서버 전용 환경 변수 시스템
    • 클라이언트 컴포넌트와 서버 컴포넌트의 완전한 코드 분할
  • 파일 시스템 기반 라우팅 자동 라우팅 설정으로 폴더 구조에 따라 경로를 효율적으로 관리할 수 있다. 동적 라우팅을 통해 /albums/[albumId] 같은 패턴을 쉽게 구현할 수 있다.

  • 성능 최적화 기능 Code Splitting으로 필요한 코드만 로드하여 초기 로딩 시간을 단축할 수 있다. 사전 로드(Prefetching)로 링크된 페이지를 미리 로드하여, 페이지 전환 시 UX를 개선할 수 있다. 비동기 요청 API : 데이터 요청이 필요 없는 컴포넌트를 비동기로 처리하여 초기 로드 속도 향상

  • 미들웨어 시스템 인증 상태에 따른 페이지 접근 제어를 효율적으로 구현할 수 있다. (특정 앨범, 보관함에 대한 접근 관리)

  • 점진적 정적 재생성(ISR) 정적 페이지를 런타임에서 효율적으로 재생성할 수 있다.

    • 자주 변경되지 않는 데이터 주기적인 업데이트
    • 생성된 페이지를 캐싱하여, 서버 부하 감소
  • SEO 최적화 MVP에는 포함되어 있지 않지만, SNS 기능 확장시에 사용될 수 있음.

Next.js 15is now stable. In Next.js 15


상태 관리

컴포넌트 상태관리

별도의 상태 관리 시스템이 필요한 이유
리액트 앱은 상태가 변경되면 리렌더링을 한다. 상태 관리를 적절하게 해주지 않으면 불필요한 리렌더링이 발생할 수 있다.
컴포넌트 간의 직접적인 데이터 전달이 어렵다. Props Drilling 이 심해질 경우 Prop의 출처를 찾기 어렵다.
따라서 복잡한 시스템을 다룰 떄는 상태 관리가 필수적이다.

Options : Redux, Zustand, Recoil 등

Recoil
아톰(atom)과 선택자(selector) 기반의 상태 관리 시스템
React 전용으로 설계됨

Zustand
단일 스토어와 선택적 구독 모델 기반 상태 관리 시스템
간결한 API와 최소한의 보일러플레이트 코드, 훅 기반 인터페이스

Redux
단일 스토어, 액션, 리듀서 기반의 Flux 패턴
예측 가능한 상태 관리를 위한 엄격한 단방향 데이터 흐름, 액션(Action)을 통한 명시적 상태 변경

컴포넌트 상태 관리 시스템 고려

도메인 로직의 복잡도에 따라서 상태 관리 라이브러리를 다음과 같이 분류할 수 있다.

< 간결                 복잡 >  
Recoil /  Zustand /  Redux    

Atom 기반의 상태 관리 시스템은 상태의 경계가 명확하고 단순한 UI 중심적인 애플리케이션에서 사용한다.
아톰이 업데이트 되면 구독하고 있는 컴포넌트들은 리렌더링이 일어난다. 아톰이 여러 군데에서 사용되면 사이드 이펙트가 발생하며 아톰간 의존성이 복잡해지면 상태 관리에 어려움이 있다.

반대로 복잡한 도메인 로직과 상태 변화를 가진 대규모 애플리케이션은 Redux를 사용한다.

본 프로젝트의 경우, 다음과 같은 데이터의 상태 관리가 필요하다.

  • 사용자 인증 및 권한
  • 앨범 및 사진
  • 지도 시각화 기능 관련 데이터 (위치 정보, 마커 클러스터 등 메타데이터)
  • 소셜 기능

또한 다음과 같은 복잡성이 존재할 수 있다.

  • 앨범, 지도, 사진, 사용자 등 데이터의 의존성 및 제약
  • 비동기 처리 (사진 업로드, 소셜 기능)
  • 공동 작업 처리

'온기'는 대규모 엔터프라이즈 시스템의 수준은 아니지만 복잡성을 지닐 것으로 예상된다.
Redux와 Zustand 모두 전역 상태 관리 기반으로 복잡한 상태 관리에 유용하지만
Redux는 Flux 패턴에 대한 전반적인 이해를 바탕으로 Action, Reducer, Provider 를 구현해야한다.
반면 Zustand는 스토어 내에서 모두 구현하고, 직관적인 인터페이스로 사용이 가능하다.
낮은 학습 곡선과 적은 보이플레이트 코드로 가볍고 유연한 Zustand가 해당 프로젝트 MVP 개발에 적합할 것으로 보인다.


서버 상태관리

서버 상태는 웹 애플리케이션의 프론트엔드와 서버 간의 데이터를 동기화하기 위해 관리되는 상태이다.
서버에서 제공되는 데이터를 나타내고 데이터베이스, 파일 시스템, 캐시 등에 저장되어 관리된다.
다중 사용자 환경에서 공유되며, 모든 클라이언트에게 동일한 데이터를 제공한다.

서버 상태를 관리함으로써 다음과 같은 작업들을 할 수 있다.

  • 로딩 상태 관리: 데이터를 가져오는 동안 사용자에게 적절한 피드백 제공.
  • 캐싱 및 동기화: 자주 사용되는 데이터를 효율적으로 관리하여 네트워크 요청을 줄임.
  • 에러 처리 및 재시도: 네트워크 문제나 서버 오류에 대한 대처와 재시도 로직 구현.
  • Stale-While-Revalidate 전략: 최신 데이터를 빠르게 제공하면서 백그라운드에서 데이터를 동기화하여 사용 경험 개선.
  • 데이터 변조 방지: 서버에서 가져온 데이터를 신뢰할 수 있도록 검증.
  • 서버 상태와 클라이언트 상태 분리: 관심사 분리로 코드 유지보수성 향상

Options : TanStack Query, SWR, Apollo Client 등

SWR
Stale-While-Revalidate 전략 간결한 데이터 페칭 라이브러리
설정이 간단하고 경량화(작은 번들 크기) 되어 있어 상대적으로 작은 프로젝트에서 효과적이다.

TanStack Query
서버 상태 특화 관리 라이브러리
효율적인 서버 상태 관리, 서버 데이터 캐싱, 자동 재검증 등을 제공한다.

Apollo Client
GraphQL 특화 데이터 관리 라이브러리

서버 상태관리 시스템 고려

온기 프로젝트에서는 서버 상태 관리에서 다음과 같은 기능이 필요하다.

  • 복잡한 상태 처리 (이미지 처리 파이프라인 관리)
  • 대용량 이미지 데이터의 효율적 관리
  • 다중 사용자 협업 환경에서 데이터 무결성을 유지하며, 실시간에 가까운 업데이트를 제공.
  • 무한 스크롤을 구현하여 이미지 데이터를 효율적으로 로드한다.
  • UX 향상을 위해 낙관적 업데이트 패턴이 필요할 수도 있다.

서버 상태 관리 라이브러리들을 표면적으로 고려하면 다음과 같다.

기능 TanStack Query SWR Apollo Client
자동 캐싱 ✓ (세밀한 제어) ✓ (기본적) ✓ (복잡)
무한 스크롤 ✓ (내장) ✓ (별도 설정) ✓ (수동 설정)
낙관적 업데이트 ✓ (간편) ✓ (수동)
재시도 매커니즘 ✓ (고도화) ✓ (기본)
웹 소켓 지원 ✓ (플러그인) ✓ (내장)

대부분 지원하는 기능이 비슷하지만, TanStack Query는 복잡한 서버 상태 관리를 간결하게 제어할 수 있다
enabled 옵션과 함수형 refetchInterval을 통해 쿼리 의존성과 동적 폴링을 명확하고 간결하게 표현한다.
쿼리 무효화 체인을 통해 이 흐름을 선언적으로 관리할 수 있다.
무한 스크롤 구현의 경우, TanStack Query의 useInfiniteQuery는 페이지 매개변수 관리, 추가 데이터 로드, 캐싱을 일관된 API로 통합하여 구현이 비교적 간단하다.
반면 SWR은 페이지 매개변수 관리를 수동으로 관리해야 하며, 상태를 직접 추적해야하는 점에서 편의성이 떨어진다.
Apollo Client도 마찬가지로 직접 구현해야 하는 부분이 많으며, GraphQL 의존성으로 어려움이 있을 것으로 예상된다.

또한 적당한 수준의 학습곡선과 Zustand 와의 역할 분리 및 호환성을 고려하였을 때 TanStack Query 가 적합할 것으로 예상된다.


Zustand

버전 Zustand 5.0.3

플럭스(Flux) 원칙 기반 중앙 상태 관리 라이브러리.
발행/구독 모델(pub/sub)기반으로 컴포넌트 밖에서도 상태 변경이 가능하다.

  • 간결한 API. 적은 보일러 플레이트 코드로 개발 속도가 향상될 것이다.
    직관적인 사용법으로 새로운 기능 개발 및 기존 코드 유지보수가 용이.
    쉬운 학습 곡선

  • 작은 패키지 사이즈

  • 복잡한 상태 관리에 용이. 업데이트 로직이 스토어 정의 내에 집중되어 있어 일관된 상태 변경에 용이하다.
    사용자 인증 정보, 앨범, 사진 메타데이터 등 다양한 상태 관리를 일관성 있고 명확하게 관리할 수 있다.
    명시적 상태 의존성.

    • 복잡한 데이터 간의 관계를 효율적으로 관리 할 수 있다. (앨범과 사진,사진과 위치데이터 등).
  • Redux Devtools 확장 프로그램 활용가능

  • TanStack 과 시너지

  • TypeScript 호환

In Zustand 5.0.3 ES 모듈 방식으로 변경.
TypeError: create is not a function 문제 해결. persist, immer, devtools 등 미들웨어 개선.

라이브러리 버전 Zustand 5.0.3 호환성 근거
React 18.x ✓ (perfect) Zustand는 React 18 버전 이상에서만 동작함.
React 19.x ✓ (good) Zustand가 React 19 지원 완료라고 밝히는 릴리스 노트는 아직 없음.
TypeScript 5.8.x ✓ (perfect) package.json에 4.5 이상 버전 명시
Next.js 15.x ✓ (perfect) Zustand.docs:Setup with Next.js

Zustand v5.0.3은 React 19과의 호환성을 지원하지만, 의존성 충돌과 Hook 명명 규칙 등 일부 설정이나 환경에서는 주의가 필요합니다.


TanStack Query

버전 TanStack Query v5.56.2

서버와의 API 통신과 비동기 데이터 관리를 효율적으로 할 수 있는 라이브러리이다.
데이터 가져오기, 데이터 캐싱, 캐시 제어 등 기능을 제공하며, 복잡한 데이터 요구 사항을 가진 애플리케이션에서 유용하다.

  • 서버 상태를 효율적으로 관리. 데이터 페칭 및 캐싱. 백그라운드 동기화. 여러 클라이언트가 동일한 서버 데이터에 접근할 수 있어 발생하는 데이터 불일치 문제를 해결할 수 있다.
    공동 작업 시 사용자 경험 향상. 로딩/에러 상태 자동 관리.

  • 쿼리 무효화 및 갱신.

  • 자동 캐싱 및 재검증. 서버 부하를 감소시킬 수 있으며,
    서버 데이터를 효율적으로 관리하려면 캐싱과 주기적인 재검증이 필요합니다.

  • 무한 스크롤 및 페이징 최적화. 내장 무한 스크롤 기능 보유. 대량의 사진 데이터 처리에 효과적.

In TanStackQuery v5.74.5

타 마이너 업데이트 버전보다 최소 10배 이상 다운로드 수가 많음 출처 : npm

  • 객체 기반 Query Key
  • 타입 추론 개선
  • 메모리 최적화 및 React 19 친화적인 구조
  • Mutation, Infinite Query 개선
기술 버전 TanStack Query 5.74.5 호환성
React 19.x ✓ (perfect)
Next.js 15.x ✓ (perfect)
TypeScript 4.7 이상 ✓ (perfect)

스타일링 도구

스타일링 도구에는 여러가지 옵션이 있지만 크게 CSS-in-JS 와 CSS-in-CSS 로 양분할 수 있다.

CSS in JS는 다음과 같은 장점이 있다.

  • 동적 스타일링 용이성
  • 런타임 성능의 최적화
  • JS 기반 애니메이션, 전환 효과
  • 유지보수성 향상

스타일링에 관련하여 현 프로젝트가 가진 특성은 다음과 같다.

  • 사진과, 지도 시각화 등 비주얼 중심 경험
  • 높은 사용자 상호작용
  • 컴포넌트 재사용

애니메이션, 전환 효과를 필요로 하지 않으며 서버 사이드 렌더링을 최소화 하고 클라이언트 사이드 렌더링을 주로 이용할 것이다.
하지만 동적 스타일링에서 오는 이점 뿐만 아니라
컴포넌트 단위 스타일링, 상태 관리와의 호환, 테마 및 디자인 시스템 관리 등에서 유용하기 때문에 CSS-in-JS 방식이 더 적합할 것으로 예상된다.

options : styled-components, Tailwind CSS, Emotion

라이브러리 Next.js 15 React 19 TypeScript 번들 크기
styled-components ✓ (설정 필요) ✓ (good) 중간
Tailwind CSS ✓ (perfect) ✓ (perfect) 추가 설정 필요 매우 작음
Emotion ✓ (perfect) ✓ (perfect) 작음
스타일링 도구들은 다른 라이브러리와는 대부분 호환이 되는 모습이다.
Next.js 와 React 호환이 우수한 Tailwind 와 Emotion을 비교해보자.
항목 Tailwind Emotion
번들 크기 매우 작음 (사용된 클래스만 포함) 중간 (런타임 라이브러리 포함)
런타임 오버헤드 없음 CSS 생성 및 삽입
CSR 성능 우수(정적 CSS) 런타임 오버헤드 존재
타입 안정성 플러그인 필요 perfect with TS
동적 스타일링 조건부 클래스 perfect with JS
개발 속도 매우 빠르다. 컴포넌트 정의 필요
학습 곡선 중간 매우 낮음
CSR과 유저 경험을 향상시키는 것이 프로젝트의 주 목적이므로 Tailwind CSS가 더 적합해 보인다.

Tailwind CSS

버전 Tailwind CSS 4.0

  • 빠른 개발 속도 유틸리티 클래스 접근 방식. MVP 개발에 적합.
  • 우수한 CSR 성능 런타임 오버헤드가 없다.
  • 컴포넌트 기반 아키텍쳐와의 높은 호환성 반복적인 UI 패턴을 일관되게 구현하기 용이하다. 반응형 디자인을 간결하게 구현할 수 있다.

Tailwind CSS 4.0is now stable. In Tailwind CSS 4.0

  • 최신 CSS 기능 지원
  • 자동 콘텐츠 감지: 템플릿 파일을 자동으로 감지하여, 별도의 구성 없이도 사용할 수 있다.
  • Oxide 엔진 도입: Rust 기반의 새로운 빌드 엔진으로, 전체 빌드 속도가 최대 10배 빠르다.

모듈 번들러

번들러 선정 시 고려해야할 요소들은 다음과 같다.

  • 빌드 속도 (초기, 점진적 빌드 속도, HMR 성능)
  • 최적화 성능 코드 분할, 트리 쉐이킹, CSS 최적화
  • 구성 용이성
  • 호환성
  • 개발자 경험
    간결한 설정, 명확한 에러 메세지, 디버깅 도구 등

options : Vite, SWC+ Webpack, esbuild 등

Vite
빠른 개발 서버 (ESM 기반, 빠른 HMR)
최적화된 빌드 (Rollup을 사용해 최적화된 번들을 생성)
추가 설정 없이 TypeScript 지원 CSS 전처리기 지원
개발/테스트/프로덕션 환경별 설정 용이

SWC + Webpack
빠른 HMR 과 빌드 속도 (다른 옵션에 비해서는 느리다.)
빠른 변환 속도 : Rust 기반
Next.js 내장 지원

esbuild
매우 빠른 빌드 속도 (Go 언어) 간결한 API 내장 최적화 TypeScript 지원

현 프로젝트의 다음과 같은 특성을 고려한다면 SWC + Webpack이 적합할 것으로 보인다.

  • Next.js 프레임워크 사용 Next.js는 SWC+Webpack 조합으로 설계되어 있어 내부 API와 기능들이 이 번들러에 최적화되어 있다.
    Vite 사용 시 Next.js의 기본 빌드 파이프라인과의 호환성 문제가 발생할 수 있다.

  • TypeScript 사용 SWR는 TypeScript 변환에서 Vite보다 빠른 성능을 지닌다

  • Webpack의 복잡한 모듈 처리 능력 우수성 대규모 어플리케이션일 수록 모듈화가 편하며 안정적이다.
    다양한 로더와 플러그인 제공.

  • 개발 환경에서 Turbopack 사용 가능 Turbo pack은 개발 서버 기능에 중점을 두고 있다. Rust 기반으로 Webpack에 비해서도 매우 빠른 성능을 가진다.


SWC + Webpack

버전 webpack 5

  • Rust 기반의 빠른 트랜스 파일링 SWC는 Rust로 작성된 트랜스파일러로, 기존 Babel 대비 10~20배 빠른 속도로 JavaScript 및 TypeScript를 변환한다.
    또한 TypeScript → JavaScript 변환이 매우 빠르다.

  • Next.js의 기본 번들러를 사용함으로써 설정 복잡성 감소 Next.js는 SWC를 내장 번들러로 채택하고 있으며, Webpack과의 연동을 고려한 최적화가 이미 적용되어 있어 별도의 복잡한 설정 없이도 성능을 확보할 수 있다.

  • 개발자 경험 우수 빌드 속도 향상, Hot Module Replacement(HMR) 반응 속도 개선. 프로덕션 번들 최적화를 안정적으로 관리

In Webpack 5

  • ECMAScript Modules를 기반으로 한 정적 분석 강화
  • Persistent Caching을 통한 재빌드 시간 단축
  • Module Federation 지원 (배포 효율성 증가)