💻 Frontend
[Frontend] utils vs lib
💡 시작하기
함수 하나 만들 때마다 “이거 utils에 넣어야 하나? lib인가…?” 이 고민을 진짜 백 번쯤 하다가 이것저것 찾아보았다. 근데 솔직히 말하면, 찾아봐도 처음엔 잘 이해가 안 됐다. 일단 최대한 내가 이해한 기준으로 정리해보겠뜸
utils vs lib, 매번 헷갈려서 정리해봄 ㅎㅅㅎ 언젠간 또 찾아볼 미래의 나를 위해 작성해보아요
1️⃣ utils
utils ? 유틸리티 폴더, 특정 기능이나 모듈에 속하지 않고 작고 일반적인 함수들을 모아두는 곳
보통 아래와 같은 함수들이 들어간다
- 날짜, 숫자 포매터
- 정렬, 파싱
- 단순 값 가공 함수
입력값을 받아 가공한 뒤 결과만 반환하는, 상태를 갖지 않고, 외부 API를 호출하지도 않으며, 비즈니스 로직과도 크게 엮이지 않는 수행하는 함수들을 이 폴더에 넣는다.
예시
// utils/formatDate.ts
export function formatDate(date: Date) {
return date.toISOString().slice(0, 10);
}
// utils/sortByDate.ts
export function sortByDate<T extends { createdAt: string }>(list: T[]) {
return [...list].sort(
(a, b) =>
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(),
);
}
특징
- 입력 → 가공 → 출력
- 외부 의존성 없음
- 비즈니스 맥락 없음
2️⃣ lib
lib ? 라이브러리 폴더, 체계적으로 구조화되어있고 재사용 가능한 코드가 저장되는 곳
utils보다 한 단계 위의 개념이라고 보면 된다.
- 특정 문제를 해결하기 위한 함수/클래스 묶음
- 내부적으로 여러 유틸 함수를 조합
- 경우에 따라 독립 패키지로 분리해도 될 정도의 단위
특징은 다음과 같다.
- 외부 라이브러리를 감싸서 사용하는 코드
- 특정 기능(인증, 결제 등)을 담당하는 로직 집합
utils에 있던 함수들이 많아져, 하나의 역할군이 되면 lib으로 옮기기도 한다.
예시
// lib/authClient.ts
import axios from 'axios';
export const authClient = axios.create({
baseURL: '/api',
withCredentials: true,
});
// lib/tokenManager.ts
import { authClient } from './authClient';
export async function refreshToken() {
const res = await authClient.post('/auth/refresh');
return res.data;
}
특징
- 특정 기능(인증)을 담당
- 외부 라이브러리(axios)에 의존
- 여러 로직이 하나의 목적 아래 묶여 있음
3️⃣ 구분 기준 (개인 견해…)
일단 나는 다음과 같은 기준으로 utils, lib 폴더 중 어디에 저장할 지를 결정하였다!
- 함수 이름만 보고 바로 역할이 보이면 →
utils - 특정 기능의 일부처럼 느껴지면 →
lib - 나중에 통째로 분리해도 될 것 같으면 →
lib
✏️ 정리
utils냐 lib이냐보다 중요한 건 코드의 책임 범위와 맥락이다.
- 책임이 작고 단순하면 utils
- 책임이 커지고 맥락이 생기면 lib
이 기준을 잡고 나서 폴더 구조 때문에 고민하는 일이 훨씬 줄었다 ㅎㅅㅎ