es-toolkit: 작은 내부 라이브러리가 글로벌 프로젝트가 된 이야기 (새 탭에서 열림)
es-toolkit은 레거시 브라우저 지원과 비효율적인 구현으로 무거워진 lodash를 대체하기 위해 Toss 내부 유틸리티 라이브러리에서 출발했습니다. 최신 브라우저 API와 ECMAScript Modules를 활용해 불필요한 코드를 제거한 결과, 함수별 성능이 최소 2배에서 10배 이상 향상되고 번들 크기도 일부 경우 30배 이상 줄었습니다. 이후 국내외 개발자들의 참여와 오픈소스 생태계의 지원을 바탕으로 크게 성장했으며, 기존 lodash 사용자가 쉽게 전환할 수 있도록 es-toolkit/compat도 개발했습니다.
lodash를 대체할 현대적인 유틸리티 라이브러리의 필요성
- 프론트엔드 개발에서는
throttle,debounce,uniq같은 유틸리티 함수가 자주 필요했습니다. - 널리 사용되던 lodash는 다음과 같은 한계가 있었습니다.
- 오래된 코드 구조를 유지함
Array#map처럼 브라우저가 기본 제공하는 기능을 직접 재구현함- Internet Explorer 등 레거시 브라우저를 위한 방어 로직을 포함함
- ECMAScript Modules를 지원하지 않아 tree-shaking이 어려움
lodash-es는 ESM을 지원했지만 lodash의 오래된 내부 구현과 비효율성은 그대로였습니다.- Toss는 자체 라이브러리인
@toss/utils를 운영했지만, 모든 함수를 직접 구현하고 다양한 엣지 케이스를 관리하는 데 큰 부담이 있었습니다.
es-toolkit의 시작과 성능 개선
- Toss 팀은 현대적인 웹 환경에 맞는 효율적인 유틸리티 라이브러리를 만들기로 했습니다.
- 핵심 목표는 lodash의 불필요한 로직을 제거하고, 브라우저 내장 API를 적극 활용하는 것이었습니다.
- 구현 결과:
- 함수에 따라 성능이 최소 2배, 최대 10배 이상 향상
- 레거시 브라우저 지원 코드와 중복 구현을 제거해 일부 번들 크기가 30배 이상 감소
- 최신 모듈 시스템을 활용해 필요한 코드만 포함할 수 있는 기반 마련
국내외 오픈소스 커뮤니티의 참여
- Toss Frontend의 소셜 미디어에 초기 결과를 공유한 뒤 예상보다 많은 사용자가 유입되었습니다.
- 커뮤니티 구성원들은 다음과 같은 방식으로 프로젝트에 기여했습니다.
- 누락된 함수 구현
- 버그 수정
- 미완성된 코드 최적화
- lodash를 es-toolkit으로 교체하는 번들러 플러그인 제작
- 유명 라이브러리의 의존성 교체
- Reddit 공유 이후 100개 이상의 추천과 수만 명의 저장소 방문이 발생했습니다.
- 해외 블로그와 뉴스레터가 프로젝트를 소개하면서 국제적인 참여가 더욱 확대되었습니다.
오픈소스 기여가 개발자 성장으로 이어진 사례
- Dayong Lee는 es-toolkit을 계기로 한국에서도 영향력 있는 오픈소스 프로젝트가 나올 수 있다는 가능성에 주목했습니다.
- Toss 직원이 아니었지만 공개 저장소에 작은 Pull Request부터 제출하며 기여를 시작했습니다.
- 지속적인 코드 리뷰와 기여를 통해 프로젝트의 두 번째로 많은 기여자가 되었습니다.
- 이 과정에서 다음을 학습했습니다.
- 인터페이스 설계 원칙
- JavaScript 언어의 세부 동작
- 협업과 코드 리뷰 방식
- es-toolkit에서 쌓은 경험은 이후 Toss Bank에 합류하는 계기가 되었습니다.
기존 사용자의 전환 장벽
- 라이브러리가 빠르게 발전했지만, 기존 lodash 사용자가 es-toolkit으로 전환하는 속도는 상대적으로 느렸습니다.
- lodash는 코드베이스 곳곳에서 다양한 함수를 사용하기 때문에 함수별로 하나씩 교체하는 작업은 큰 부담이었습니다.
- 또한 lodash는 가능한 많은 입력과 예외 상황을 처리하는 반면, es-toolkit은 주요 사용 사례에 집중했습니다.
- 따라서 동일한 이름의 함수를 단순히 교체하면 일부 상황에서 동작 차이로 런타임 오류가 발생할 수 있었습니다.
es-toolkit/compat을 통한 점진적 마이그레이션
- es-toolkit 팀은 import 문만 바꿔도 사용할 수 있는 lodash 호환 계층의 필요성을 발견했습니다.
es-toolkit/compat은 lodash의 인터페이스와 실제 동작을 최대한 유지하면서 내부 구현만 현대화하는 방식으로 설계되었습니다.- 이를 통해 사용자는 대규모 코드 수정 없이도 다음 효과를 얻을 수 있습니다.
- 기존 lodash 사용 방식 유지
- 더 빠른 내부 구현 활용
- 점진적으로 es-toolkit 표준 API로 마이그레이션
- 즉, 완전한 재작성보다 낮은 비용으로 성능과 번들 크기 개선을 먼저 경험하게 하는 전략입니다.
실용적인 결론
레거시 라이브러리를 교체할 때는 단순히 더 빠른 구현을 제공하는 것만으로는 충분하지 않습니다. 기존 API와 동작을 유지하는 호환 계층을 함께 제공하면 대규모 코드베이스의 전환 장벽을 크게 낮출 수 있습니다. 새로운 프로젝트에는 es-toolkit을 직접 사용하고, 기존 lodash 프로젝트에는 es-toolkit/compat을 활용한 단계적 마이그레이션을 고려할 수 있습니다.