Zod vs Valibot vs Yup 2026 — TypeScript 스키마 검증 라이브러리 실전 비교
조드(Zod) vs 발리봇(Valibot) vs 얍(Yup) TypeScript 스키마 검증 비교. 타입 추론·번들·엣지 런타임·React Hook Form·tRPC 연동·마이그레이션 비용을 표로 정리한다. 신규 Next.js·API·폼 검증 표준을 고르는 개발자용 vs-comparison 가이드. 런타임 타입 안전성·서버 액션·클라이언트 번들 예산 기준으로 선택한다.
폼 입력을 받을 때마다, API 바디를 파싱할 때마다, 환경변수 한 줄을 읽을 때마다 — TypeScript 프로젝트는 런타임 검증 문제를 다시 만납니다. 컴파일 타임 타입은 배포 뒤에 날아간 요청·잘못된 JSON·빈 문자열을 막아 주지 않습니다.
이 글은 가장 자주 맞붙는 세 라이브러리 — 조드(Zod), 발리봇(Valibot), 얍(Yup) — 을 표 중심으로 비교합니다. 벤치 수치를 지어내지 않고, 공식 문서의 API·번들 철학·생태계를 기준으로 언제 무엇을 고를지만 남깁니다.
한 줄 결론 — 누구에게 무엇이 맞는가
새 프로젝트·tRPC·React Hook Form 조합이면 조드, 번들 크기·모듈 단위 임포트·엣지 함수가 우선이면 발리봇, 기존 폼 코드가 얍 스키마로 가득하거나 Formik 레거시면 얍을 유지·점진 이전이 기본 축입니다.
세 도구 모두 “스키마를 정의하고 값을 파싱한다”는 역할은 같습니다. 갈리는 지점은 타입 추론의 매끄러움, 패키지 분할 방식, 커뮤니티 예제 양, 기존 코드베이스 관성입니다. 먼저 골격 표로 잡습니다.
항목
조드
발리봇
얍
주 언어
TypeScript 우선
TypeScript 우선
JS/TS 모두(역사적으로 JS 폼)
타입 추론
강함(z.infer)
강함(InferOutput 등)
가능하나 조드·발리봇 대비 덜 매끄러운 경우 많음
번들 철학
단일 패키지 중심, 기능 풍부
함수·모듈 단위 트리셰이킹 강조
전통적 스키마 빌더
생태계
가장 넓음(tRPC, RHF 등)
빠르게 성장, 어댑터 증가
Formik·레거시 폼 예제 다수
이런 때 1순위
신규 TS 앱·팀 표준
엣지·번들 민감
기존 Yup 스키마 유지
표의 “강함/넓음”은 절대 벤치마크 순위가 아닙니다. 본인 저장소의 스키마 개수·클라이언트 번들 예산·이미 깔린 어댑터를 먼저 재세요.
스키마 작성 API — 체이닝 vs 함수 조합
세 라이브러리의 체감 차이는 첫 스키마를 칠 때 바로 납니다. 조드와 얍은 메서드 체이닝이 익숙하고, 발리봇은 작은 함수를 조합하는 쪽에 가깝습니다.
조드 예시는 문서에서 흔히 보는 형태입니다. 문자열·숫자·객체·배열을 z.object로 묶고, .min·.email·.optional 같은 수식어를 이어 붙입니다. 팀 온보딩 자료와 블로그 예제가 많아, 신입이 검색으로 답을 찾기 쉽습니다.
발리봇은 object, string, pipe, minLength처럼 필요한 함수만 임포트하는 패턴을 강조합니다. 스키마가 커져도 “쓰지 않은 검증 로직이 번들에 덜 섞이게” 설계 의도가 문서에 분명히 적혀 있습니다. 체이닝에 익숙한 사람에게는 처음 한 시간이 낯설 수 있습니다.
얍은 yup.object({ ... })와 yup.string().required() 체인이 고전입니다. 폼 필드 단위 검증 예제가 오래 쌓여 있어, 레거시 코드 읽기에는 유리합니다. 다만 최신 TypeScript 추론·엔드 투 엔드 타입 공유 패턴은 조드·발리봇 문서 쪽이 더 풍부한 편입니다.
관점
조드
발리봇
얍
학습 곡선
낮음~중간
중간(함수 조합 적응)
낮음(폼 경험자)
코드 스타일
체이닝
함수·파이프
체이닝
스키마 재사용
extend·merge·pick 등
조합·재export 용이
shape 확장 패턴
문서·예제 양
매우 많음
공식 문서 충실, 커뮤니티 증가 중
폼 중심 예제 다수
실무 팁: 팀 컨벤션을 정할 때 “어느 라이브러리가 더 멋진가”보다 스키마 파일 위치, 에러 메시지 언어, parse vs safeParse 정책을 먼저 고정하세요. 도구보다 규칙이 깨지면 세 라이브러리 모두 유지보수가 지옥입니다.
런타임 검증 라이브러리 선택은 API 취향보다 번들 예산과 팀 생태계 관성으로 가르는 편이 빠르다
타입 추론 비교 — 스키마가 곧 타입인가
TypeScript 팀에서 조드가 빠르게 표준이 된 이유 중 하나는 스키마에서 타입을 끌어내는 흐름이 단순하기 때문입니다. z.infer<typeof schema> 한 줄로 입력·출력 타입을 맞추는 패턴이 널리 공유됩니다. 서버 액션 인자, tRPC 프로시저, 환경변수 로더까지 같은 습관을 쓸 수 있습니다.
발리봇도 입력·출력 타입을 분리해 추론하는 API를 공식 문서에서 제공합니다. 변환(transform)이 끼면 “검증 전 타입”과 “검증 후 타입”이 달라지므로, InferInput / InferOutput 구분을 의식하는 편이 안전합니다. 조드 역시 입출력 변환을 지원하지만, 팀이 이미 조드 관용구에 익숙하면 학습 비용이 거의 없습니다.
얍은 타입 정의를 스키마와 병행하거나, 제네릭·유틸로 추론을 붙이는 패턴이 섞여 있습니다. 순수 JavaScript 시절부터 쌓인 코드베이스에서는 문제없지만, “스키마 하나만 진실의 원천”을 강하게 밀어붙이는 팀에서는 조드·발리봇이 덜 거슬립니다.
시나리오
유리한 쪽
이유
API 입출력 타입 공유
조드 또는 발리봇
infer 패턴·TS 문서 풍부
문자열→숫자 변환 후 타입
세 도구 모두 가능
transform 위치·에러 처리 스타일 차이
점진적 JS→TS 이전
얍 유지 후 부분 이전
기존 스키마 재사용
엄격한 end-to-end 타입
조드(+tRPC 등)
생태계 예제가 가장 많음
주의: 어떤 라이브러리든 any를 스키마에 섞거나 as 단언으로 우회하면 추론 이점이 사라집니다. 비교표보다 safeParse 결과를 좁혀 쓰는 습관이 프로덕션 안정성에 더 직접적입니다.
번들 크기와 엣지 런타임 — 클라이언트·미들웨어 기준
서버 전용 검증만 한다면 번들 차이는 체감이 작을 수 있습니다. 반대로 브라우저 폼 검증, 엣지 미들웨어, 워커에 스키마를 실으면 패키지 철학이 의사결정에 들어옵니다.
발리봇은 공식 포지셔닝 자체가 모듈러·트리셰이킹 친화입니다. 필요한 스키마 함수만 가져오도록 설계되어, “전체 검증 키트를 한 번에 넣는” 패턴을 피하려는 팀에 맞습니다. 조드도 최적화가 계속되지만, 기능 표면이 넓어 클라이언트로 그대로 끌어올 때는 import 경계를 의식해야 합니다.
얍은 레거시 폼과 함께 클라이언트에 올라간 사례가 많습니다. 스키마가 폼 전용으로 작으면 문제없고, 거대한 공유 스키마 모듈을 클라이언트 번들에 통째로 넣으면 세 도구 모두 비용이 커집니다. 라이브러리 교체보다 서버/클라이언트 스키마 분리가 먼저인 경우가 흔합니다.
배치 위치
추천 후보
실무 메모
Node API 서버만
조드(표준)·발리봇·얍
팀 익숙도 우선
엣지·워커
발리봇 검토
import 단위·콜드스타트 민감
브라우저 폼
조드 또는 발리봇
어댑터·필드 에러 매핑 확인
레거시 Formik
얍 유지
전면 교체 ROI 계산
번들 크기를 숫자로 단정하려면 본인 앱의 스키마 집합으로 @next/bundle-analyzer 등으로 측정하는 것이 맞습니다. 이 글에 임의의 kB 순위를 박아 두지 않습니다. 측정 전에는 “클라이언트에 스키마를 얼마나 실을지”만 결정하세요.
검증 라이브러리는 혼자 쓰이지 않습니다. React Hook Form, Formik, tRPC, Next.js 서버 액션, 오픈API 생성기와의 연결 밀도가 실제 생산성을 좌우합니다.
조드는 이 축에서 사실상 기본값에 가깝습니다. React Hook Form 리졸버, tRPC 입력 스키마, 각종 코드젠·예제 저장소가 조드를 전제로 하는 경우가 많습니다. “검색했을 때 답이 나온다”는 팀 비용 절감입니다.
발리봇은 공식·커뮤니티 어댑터가 늘고 있고, 모듈러 설계를 살린 연동 문서가 정비되어 있습니다. 다만 팀 내부 위키에 조드 예제만 가득하다면 온보딩 자료를 다시 써야 합니다. 생태계 공백을 과장할 필요는 없지만, 복사해 쓸 스니펫 양은 아직 조드가 앞서는 편입니다.
얍은 Formik 시절부터 폼 검증의 표준 후보였습니다. 오래된 사내 어드민, 마케팅 랜딩 폼, 외부 기여자 PR에 얍 스키마가 남아 있는 경우가 흔합니다. 새 기능을 조드로 짜고 레거시만 얍으로 두는 이중 표준도 가능하지만, 장기적으로는 하나로 모으는 편이 리뷰 비용이 줄어듭니다.
tRPC / end-to-end 타입 — 조드 예시가 압도적으로 많음
React Hook Form — 조드 리졸버가 기본 선택지로 자주 등장, 발리봇·얍 경로도 존재
Formik — 얍 연동 자료가 역사적으로 풍부
서버 액션 입력 검증 — 조드·발리봇 모두 적합, 팀 표준 우선
선택 기준을 한 문장으로 줄이면: 이미 팀이 쓰는 폼·RPC 스택의 공식 예제가 어느 스키마를 가리키는가입니다.
에러 메시지·다국어·커스텀 검증
프로덕션에서 스키마가 실패하면 사용자는 “Invalid” 영문 한 줄이 아니라 어떤 필드가 왜 틀렸는지를 봐야 합니다. 세 라이브러리 모두 커스텀 메시지와 경로(path) 정보를 제공할 수 있습니다.
조드는 .refine / .superRefine 으로 교차 필드 검증(비밀번호 확인, 시작일·종료일)을 붙이는 패턴이 널리 공유됩니다. 에러 이슈 배열을 UI 필드 키에 매핑하는 헬퍼도 커뮤니티에 많습니다.
발리봇은 파이프 안에서 검증 단계를 나누고, 메시지·이슈 구조를 문서화합니다. 모듈 단위로 커스텀 체크를 재사용하기 좋게 짜는 팀에 잘 맞습니다.
얍은 test 메서드와 동기·비동기 검증 전통이 있습니다. 서버에 중복 이메일 확인을 넣는 식의 비동기 테스트 예제가 폼 튜토리얼에 많이 남아 있습니다. 다만 최신 앱에서는 비동기 검증을 스키마보다 서버 액션·API 응답 쪽으로 옮기는 설계도 흔합니다.
요구사항
실무 접근
한글 에러 메시지
세 도구 모두 커스텀 메시지 가능 — 메시지 사전을 스키마 밖에 두고 키로 주입
필드 경로 매핑
safeParse 실패 시 issues/errors를 폼 라이브러리 setError로 연결
교차 필드
객체 단위 refine/test — UI와 서버에 동일 규칙 복제 금지, 공유 스키마 1곳
비동기 중복 검사
스키마 최소 규칙 + API 검증 권장(타임아웃·레이스 관리)
다국어 앱이라면 스키마 파일에 한글 문장을 하드코딩하기보다 에러 코드 → i18n 키 매핑을 두는 편이 세 라이브러리 모두에 유리합니다. 라이브러리 교체 시에도 UI 번역 레이어가 남습니다.
마이그레이션 비용 — Yup에서 Zod, Zod에서 Valibot
전면 교체는 스키마 개수에 비례해 비용이 붙습니다. 현실적인 경로는 보통 다음 세 가지입니다.
신규 모듈만 조드(또는 발리봇) — 레거시 얍 스키마는 손대지 않음. 이중 의존이 생기지만 리스크가 가장 낮음.
경계부터 교체 — 외부 API 입력, 웹훅, 환경변수 로더처럼 테스트하기 쉬운 경계 스키마부터 이전.
한 도메인 수직 슬라이스 — 회원가입·결제 같은 한 플로우의 폼+API를 한꺼번에 맞춰 사용자 경로를 깨지 않음.
얍 → 조드: 개념(string/number/object/array, required, nullable)은 대응 가능하지만, 메서드 이름·기본값·빈 문자열 처리가 다릅니다. 특히 폼에서 빈 입력을 undefined로 볼지 ""로 볼지 정책을 먼저 통일하세요.
조드 → 발리봇: 타입 추론 철학은 가깝지만 API 표면이 다릅니다. 자동 변환 스크립트에 과도하게 기대기보다, 핵심 스키마 10~20개를 손으로 옮기며 팀 스타일 가이드를 만드는 편이 안전합니다. 번들 이득이 측정으로 증명되지 않으면 교체 ROI가 안 나올 수 있습니다.
발리봇 → 조드: 반대로 생태계·채용·예제 양 때문에 되돌리는 팀도 있습니다. “표준 스택” 요구가 강한 조직에서는 조드 단일화가 온보딩에 이득일 수 있습니다.
현재 상태
추천 움직임
얍 50개+ · 신규 기능 많음
신규만 조드, 레거시는 동결
조드 정착 · 엣지 번들 이슈
엣지 경로만 발리봇 파일럿 후 측정
그린필드 TS 앱
조드 기본, 번들 제약이 크면 발리봇
스키마 10개 미만
한 번에 통일 가능 — 주저하지 말 것
마이그레이션은 전면 교체보다 경계 스키마·신규 모듈부터 옮기는 편이 장애 면적이 작다
상황별 선택 매트릭스 — 표로 끝내기
아래 표만 팀 위키에 붙여도 회의 시간이 줄어듭니다. 예외가 있으면 “왜 예외인지” 한 줄만 남기세요.
상황
1순위
2순위
비고
Next.js + tRPC 신규
조드
발리봇
예제·채용 표준
워커·엣지 검증
발리봇
조드(경량 스키마)
번들 측정 필수
Formik 레거시
얍
점진 조드
전면 교체 비추천
React Hook Form 신규
조드
발리봇
리졸버 문서 확인
오픈소스 라이브러리 공개
조드 또는 피어 의존
발리봇
사용자 스택 충돌 최소화
1인 사이드 프로젝트
조드
발리봇
검색 비용 최소화
세 라이브러리 중 “틀린” 선택은 거의 없습니다. 틀린 것은 스키마 없이 any로 API를 받는 것, 그리고 클라이언트·서버에 서로 다른 규칙을 복제해 어긋나는 것입니다.
실무 체크: 도입 전에 (1) 서버 전용인지 클라이언트 공유인지, (2) 기존 폼 라이브러리, (3) tRPC/서버 액션 사용 여부, (4) 번들 분석 가능 여부 — 네 가지만 팀에 물어보세요. 답이 나오면 위 표에서 1순위가 거의 정해집니다.
참고 자료
비교에 사용한 공식·1차 자료입니다. API·패키지 구조는 버전마다 바뀔 수 있으니 도입 직전 문서를 다시 확인하세요.
대부분의 TypeScript 웹 앱은 조드로 시작하면 예제·채용·연동 비용이 가장 낮습니다. 엣지 번들이나 모듈 단위 임포트가 측정 가능한 병목이면 발리봇 파일럿을 권합니다. “더 최신”이라는 이유만으로 바꾸지 마세요.
얍을 지금 신규 프로젝트에 써도 되나요?
동작은 합니다. 다만 신규 TypeScript 스택이라면 조드나 발리봇이 타입 추론·생태계 면에서 선택지가 넓습니다. 팀 전원이 얍에만 익숙하고 스키마가 폼에만 쓰인다면 얍도 합리적입니다.
클라이언트와 서버에 같은 스키마를 공유해도 되나요?
공유 패키지(또는 모노레포 패키지)로 두는 패턴이 흔합니다. 다만 서버 전용 비밀 필드·무거운 의존이 스키마 파일에 섞이지 않게 경계를 나누세요. 클라이언트에는 폼에 필요한 부분집합만 export 하는 편이 안전합니다.
parse와 safeParse 중 무엇을 써야 하나요?
사용자 입력·외부 API처럼 실패가 일상인 경로에는 safeParse(또는 동등 API)로 분기하는 편이 낫습니다. 내부적으로 이미 검증된 값에 다시 스키마를 적용할 때 throw형 parse를 쓰는 팀도 있습니다. 중요한 것은 실패 시 로그·사용자 메시지 정책을 통일하는 일입니다.
성능 벤치마크 순위가 선택 기준이 되나요?
대부분의 비즈니스 API에서 스키마 검증 시간은 네트워크·DB보다 작습니다. 초당 요청이 극단적으로 많거나 엣지 콜드스타트가 민감한 경우가 아니면, 생태계와 유지보수성을 우선하세요. 필요하면 본인 스키마로 프로파일링하세요.
zod와 zod/v4 같은 메이저 변경은 어떻게 대비하나요?
메이저 버전은 import 경로·기본 동작이 바뀔 수 있습니다. 락파일에 버전을 고정하고, 업그레이드 시 공식 마이그레이션 노트를 따른 뒤 CI에서 스키마 단위 테스트를 돌리세요. 발리봇·얍도 동일하게 릴리스 노트를 확인합니다.