TypeScript용 초경량 고성능 스키마 검증기
JIT 컴파일과 zero-copy로 정상 경로 할당을 피하는 TypeScript 스키마 검증 라이브러리
TL;DR
Loyd는 TypeScript용 경량 스키마 검증 라이브러리로서 JIT 컴파일, zero-copy 실행, 룰 지문화 같은 최적화를 조합해 정상 경로의 할당을 최소화하고 처리량을 높입니다. 벤치마크에서 AJV 대비 다수 항목에서 우위를 보이며 AOT Vite 플러그인과 트리 쉐이킹 친화적 패키지 설계로 프런트엔드 번들 크기를 낮출 수 있습니다. Node ≥20, TypeScript ≥5.4, tsconfig의 strict:true 환경에서 사용하도록 권장되며 Zod 마이그레이션 도구와 React 훅을 포함한 생태계를 제공합니다.
주요 기능
- Loyd는 스키마별로 JIT(compiled) 검증 함수를 생성해 반복 호출에서 스키마 트래버설과 디스패치를 제거합니다. 이 접근은 대량 데이터나 스트리밍 검증처럼 반복 호출이 많은 워크로드에서 지연과 CPU 사용량을 낮춥니다. README 벤치마크에서는 AJV 대비 여러 케이스에서 우위를 보이는 근거가 제시되어 있습니다.
- 성공 경로에서 결과 객체 할당을 피하는 zero-copy 실행기를 제공해 GC 압박을 줄입니다. createExecutor로 zeroCopy, abortEarly, freeze, strict 같은 옵션을 조합해 실행 정책을 맞출 수 있으므로 다양한 운영 환경에 적용하기 쉽습니다. 특히 높은 성공률을 보이는 입력 검증 파이프라인에서 비용 절감 효과가 뚜렷합니다.
- 에러 경로의 필드 경로를 컴파일 타임 리터럴로 고정해 정상 흐름에서 경로 객체 할당을 회피합니다. 오류가 발생할 때만 경로 배열이 생성되므로 일반적인 요청 처리에서는 메모리 할당과 관련된 오버헤드가 거의 없습니다. 이 설계는 희귀한 오류 발생 시에도 명확한 경로 정보를 유지하는 균형을 제공합니다.
- 트리 쉐이킹 친화적 패키지 구조와 0.8kb 수준의 핵심 번들 크기를 목표로 설계되어 필요한 모듈만 가져오는 방식으로 번들 크기를 최소화합니다. @loydjs/schema 같은 모듈을 선택적으로 import하면 사용하지 않는 코드가 번들에 포함되지 않습니다. 프런트엔드 환경에서 번들 예산이 중요한 프로젝트에 적합합니다.
어떻게 동작하는가
Loyd는 사용자가 정의한 스키마를 입력으로 받아 두 단계로 동작합니다. 첫 번째는 compile(schema)를 통해 스키마별로 순수 JS 검증 함수를 JIT으로 생성하고 캐시하는 단계로, 이후 호출은 생성된 함수를 직접 실행해 스키마 트래버설과 재귀 호출을 회피합니다. 두 번째는 실행기 레이어로 zero-copy 실행기와 두 패스 비동기 파이프라인을 통해 성공 경로의 할당을 건너뛰고 동기 규칙이 통과한 경우에만 비동기 룰을 병렬 실행해 비용을 줄입니다.
해결 문제
런타임 스키마 검증에서 반복 호출에 따른 분기·할당 오버헤드와 번들 크기 문제를 줄입니다. JIT 컴파일과 인라인된 오류 경로로 정상 흐름의 힙 할당을 최소화하고 zero-copy 실행기로 성공 경로에서 객체 할당을 건너뛰어 GC 비용을 낮춥니다. 또한 Vite AOT 플러그인과 tree-shakable 모듈 구조로 프런트엔드 번들 예산까지 제어할 수 있게 합니다.
지금 주목받는 이유
공개 벤치마크에서 Loyd가 AJV 대비 13/15 항목에서 더 빠른 결과를 보였다는 점이 주목을 받았습니다. 핵심 기능인 JIT 컴파일, zero-copy 실행, AOT Vite 플러그인 조합이 프런트엔드와 백엔드 양쪽에서 번들 크기와 런타임 비용을 동시에 낮출 수 있어 인기를 얻고 있습니다. 또한 tree-shakable 패키지 설계와 Zod 호환성 도구는 기존 코드베이스 전환을 고려하는 팀의 관심을 끌고 있습니다.
차별점
- 정적 인라인 경로 방식을 통해 오류 경로를 컴파일 시 리터럴로 삽입하고 정상 흐름에서는 경로 객체 할당을 회피합니다. 이 기법은 오류가 드문 서비스에서 메모리 할당 비용을 거의 제거하면서도 오류 발생 시 명확한 경로 정보를 제공합니다. 동일한 목적을 가진 라이브러리들과 달리 경로 문자열을 런타임에 생성하지 않는 점이 구별됩니다.
- side-effect-aware codegen으로 변경 가능한 필드만 쓰기 연산을 수행하도록 코드 생성을 최적화해 불필요한 속성 쓰기를 건너뜁니다. number나 boolean 같은 불변 타입 필드는 쓰기-백(write-back) 단계를 생략해 검사 시의 메모리·CPU 비용을 낮춥니다. 이 방식은 특히 검증 과정에서 불필요한 할당이나 객체 복사를 줄여 처리량을 높입니다.
- rule fingerprinting 기법으로 각 검증 룰의 동작을 컴파일 타임에 분석해 단순 조건은 재귀 호출 대신 인라인 비교로 치환합니다. 이렇게 생성된 flat inline 코드는 호출 오버헤드와 런타임 헬퍼 의존도를 줄여 깊게 중첩된 규칙이나 큰 배열 검증에서 성능 이점을 제공합니다. README 벤치마크는 이러한 최적화가 AJV 대비 여러 워크로드에서 우위를 만든다고 보고하고 있습니다.
사용 사례
- 대량 레코드나 스트리밍 데이터 검증처럼 반복 검증 호출이 많은 서버 사이드 파이프라인에서 유리합니다. JIT으로 생성된 검증 함수와 zero-copy 실행기로 반복적인 스키마 트래버설과 할당을 줄여 처리량을 개선할 수 있습니다. 벤치마크에서 제시된 다수 케이스는 이 상황에서 Loyd의 성능 우위를 뒷받침합니다.
- 프런트엔드 애플리케이션에서 번들 크기 제약이 있는 경우에 적합합니다. @loydjs/schema의 트리 쉐이킹과 AOT Vite 플러그인을 활용하면 런타임 컴파일 코드를 번들에 포함시키지 않고도 검증 로직을 유지할 수 있습니다. 특히 SPA에서 폼 검증 라이브러리를 경량화하려는 시나리오에서 이점이 큽니다.
- 비동기 유효성 검사(예: 데이터베이스 중복 검사)를 포함한 폼 처리에서 비용을 제어할 때 유용합니다. 두 패스 비동기 파이프라인은 동기 검사 실패로 인한 불필요한 비동기 호출을 차단하고, 비동기 규칙은 동기 통과 시에만 Promise.all로 병렬 실행됩니다. 이 구조는 외부 호출 비용을 줄이는 동시에 응답성을 유지합니다.
시작하기
프로젝트는 @loydjs/schema, @loydjs/core, @loydjs/types 같은 코어 패키지를 설치하고 strict TypeScript 환경에서 사용하도록 설계되어 있습니다. JIT 컴파일이 필요하면 @loydjs/compiler를 추가하고, 런타임 최적화를 활용하려면 @loydjs/runtime과 optional 패키지들을 설치하면 됩니다. README에 npm 설치 명령과 예제 코드가 제공되며 Vite AOT 플러그인 사용 예시도 포함되어 있어 초기 설정을 빠르게 진행할 수 있습니다.
요구사항
- Node.js ≥ 20 이상이 필요하며 README가 해당 런타임을 요구한다고 명시되어 있습니다. 런타임 버전이 낮으면 JIT 동작이나 일부 런타임 최적화가 예상대로 동작하지 않을 수 있습니다. 따라서 프로젝트를 도입하기 전 CI와 배포 환경의 Node 버전을 확인해야 합니다.
- TypeScript ≥ 5.4 및 tsconfig.json의 "strict": true 설정을 요구합니다. 타입 유추와 Infer<> 같은 타입 헬퍼들이 엄격 모드에서 정확히 동작하도록 설계되어 있으므로 strict 모드를 권장합니다. 기존 레포에서 strict:false인 경우 설정 변경과 타입 오류 정리가 필요할 수 있습니다.
- 빌드 시 AOT 플러그인을 사용하려면 Vite/Rollup 등 정적 번들러 환경에서 스키마가 정적으로 해석 가능해야 합니다. loydPlugin()은 빌드 타임에 스키마를 대체하므로 동적 생성 스키마나 런타임 의존 스키마는 AOT 변환 대상에서 제외될 수 있습니다. 빌드 파이프라인에 맞춰 스키마 선언 방식을 조정해야 AOT 이점을 온전히 누릴 수 있습니다.
벤치마크
| 벤치마크 | 지표 | 값 | 비교 |
|---|---|---|---|
| string valid | relative speed | Loyd compiled: fastest; AJV 5.36× slower | — |
| object deep valid | relative speed | Loyd compiled: fastest; AJV 1.71× slower | — |
| array 1000 valid | relative speed | Loyd compiled: fastest; AJV 1.43× slower | — |
| AJV coverage | benchmarks beat count | Beats AJV on 13/15 benchmarks | — |
이미지 분석
118
Stars
6
Forks
+204
Trending
0
조회수
관련 토론
아직 관련 토론이 없습니다.
댓글
댓글을 작성하려면 로그인이 필요합니다.