Joi vs Yup
어떤 JSON 라이브러리를 쓸까?
기본
| Joi | Yup | |
|---|---|---|
| 주간 다운로드 | 2375만 | 1236만 |
| 최근 릴리스 | 릴리스 없음 | 1279일 전 |
| 유지보수 | 정체 | 정체 |
| 열린 이슈 | 203 | 249 |
유지보수 상태는 최근 릴리스 간격만으로 판정합니다 (90일 이내 활발 · 270일 이내 둔화 · 그 이상 정체).
쓰다 보면 만나는 것
Joi
- 거슬림
joi는 최소화 기준 약 145~149KB로, 프런트엔드용 경량 대안(zod·yup)보다 용량이 커서 브라우저 번들에 포함하면 크기가 늘어난다.
joi는 서버사이드 검증을 전제로 설계돼 Express/Hapi 등 서버 API 검증에 적합하다. 최소화 기준 약 145~149KB로, 프런트엔드를 겨냥해 설계된 zod(약 13KB)나 yup(약 12~20KB)보다 용량이 크다. 클라이언트 폼 검증에서 번들 크기가 중요하다면 zod·yup 같은 경량 대안을 고려하는 것이 우회법이다.
2026-05 · 미해결
- 거슬림
joi가 2020년 7월 @hapi 조직에서 분리되며 패키지명이 plain joi로 바뀌었고, 기존 @hapi/joi는 'Switch to npm install joi' 문구와 함께 deprecated 되어 마지막 릴리스 17.1.1(2020년 3월)에 고정됐다. 옛 문서를 따라 @hapi/joi를 설치하면 이후 갱신이 끊긴 버전을 받는다.
2020년 7월 joi 관리자가 @hapi 조직에서 나오면서 GitHub 저장소는 sideway/joi로, npm 패키지명은 plain `joi`로 이관됐다(이슈 #2411). 이에 따라 @hapi/joi에는 'Switch to npm install joi' deprecation 문구가 붙었고, 마지막 릴리스인 17.1.1(2020년 3월) 이후 갱신이 없다. 오래된 튜토리얼이나 이행 의존성 트리가 여전히 @hapi/joi를 참조하면 기능·보안 갱신이 끊긴 버전을 끌어오므로, 명시적으로 `joi`로 교체해야 한다.
2026-08 · 미해결 · @hapi/joi (deprecated, ≤17.1.1)
Yup
- 거슬림
복잡한 스키마(nullable/optional 필드, 중첩 객체, 조건부 필드·변환)에서 yup의 InferType가 추론한 TypeScript 타입이 실제 검증 결과를 정확히 반영하지 못하는 경우가 있다.
yup.InferType는 nullable 필드나 중첩 객체를 조합하면 실제 스키마와 다른 타입을 내는 경우가 있고(예: nullable 문자열에 .default(null)를 주지 않으면 타입 불일치가 보고됨), object와 shape 사용 방식에 따라 인텔리센스가 제공되지 않거나 인덱스 시그니처 관련 타입 에러가 나기도 한다. 이 때문에 스키마와 별개로 인터페이스를 손으로 선언하거나 우회하는 사례가 있다. 독립 비교 글은 조건부 필드·변환·중첩 객체가 있는 복잡한 스키마에서 추론 타입이 검증 결과를 정확히 반영하지 못한다고 같은 계열의 한계로 서술하고, GitHub 이슈는 object/shape 인텔리센스와 nullable 필드 타입 처리 문제를 개별 재현으로 보고한다.
2026-03 · 미해결