0ju-log
💻 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

이 기준을 잡고 나서 폴더 구조 때문에 고민하는 일이 훨씬 줄었다 ㅎㅅㅎ

🔗 참고