원문 캡처 · github.com
원문 캡처 · github.com

Rust로 만든 tsgolint-rust는 oxlint의 타입 인식 린터인 tsgolint를 대체한다. 프로젝트 12개를 대상으로 한 비교에서 Go 버전보다 린트 속도가 1.31~2.68배 빨랐고, 측정된 각 프로젝트에서 메모리 사용량도 적었다.

tsgolint-rust는 oxc-project/tsgolint의 v7.0.2004를 Rust로 옮긴 구현이다. TypeScript Go 대신 TypeScript 7을 Rust로 포팅한 ts-rust를 사용한다. oxlint가 같은 방식으로 실행하고 같은 headless 입력을 보내면 진단, 수정 사항, 제안을 돌려주는 드롭인 대체품이다.

프로젝트는 60개 규칙과 옵션, 메시지, 수정 및 제안을 지원한다. tsgolint의 Go 테스트 스위트 7,619개 사례 중 7,591개가 통과하고, 나머지 28개는 tsgolint 자체에서 건너뛴다. oxlint 1.86.0의 CLI 테스트 25개에서도 --fix를 포함해 두 바이너리의 출력이 같았다. 실제 프로젝트 비교에서 남은 차이는 TypeScript 버전 차이, tsgolint 실행 간 변동, Effect 진단에서 비롯됐다고 프로젝트는 설명한다.

속도와 메모리 비교

같은 12코어 머신에서 60개 규칙을 적용해 수정 및 제안 기능을 켜고, Go 버전과 번갈아 7회 실행한 중앙값이다. 메모리는 최대 사용량이며 Go와 Rust 순으로 표기했다.

프로젝트파일 수Gotsgolint-rust속도 향상최대 메모리, Go / Rust
TanStack Query core680.85초0.51초1.67배489 / 310 MB
TanStack Query React, --type-check 적용631.07초0.50초2.14배520 / 279 MB
h31770.64초0.49초1.31배349 / 243 MB
hono3121.91초1.29초1.48배811 / 498 MB
hono, --type-check 적용3122.70초1.21초2.23배1060 / 507 MB
t3code contracts, --type-check 적용1072.52초0.94초2.68배955 / 471 MB
t3code shared2161.16초0.72초1.61배600 / 355 MB
Effect (packages/effect/src)5163.77초2.54초1.48배1411 / 863 MB
t3code web chat2245.13초3.24초1.58배2438 / 1469 MB

두 구현은 같은 네 개의 검사기를 실행한다. t3code web chat에서 tsgolint-rust의 사용자 CPU 시간은 10.3초로 Go 버전의 26.0초보다 짧았다. 네이티브 빌드에는 jemalloc과 fat LTO를 사용한다. WASI 빌드는 한 번에 검사기 하나만 유지하므로 네이티브 빌드 메모리의 약 절반을 쓴다. 예를 들어 TanStack Query core는 168 MB, --type-check를 적용한 hono는 216 MB를 사용했다.

설치와 제약

패키지는 tsgolint-rust라는 이름으로 배포되지만, oxlint가 찾는 oxlint-tsgolint 이름으로 별칭을 지정해 설치해야 한다. oxlint는 oxlint-tsgolint@>=7.0.2003을 선택적 피어 의존성으로 선언한다. tsgolint-rust는 자체 버전을 사용하므로 패키지 관리자에 해당 버전을 허용하도록 설정해야 한다. 그렇지 않으면 pnpm은 피어 의존성 경고를 내고 npm은 설치를 거부한다.

pnpm에서는 package.json에 별칭을 추가하고 pnpm-workspace.yaml에서 허용 버전을 지정한다.

json
{
 "devDependencies": {
 "oxlint": "^1.86.0",
 "oxlint-tsgolint": "npm:tsgolint-rust@0.1.0"
 }
}
yaml
peerDependencyRules:
 allowedVersions:
 "oxlint>oxlint-tsgolint": "*"

npm에서는 같은 별칭과 재정의를 package.json에 추가한다.

json
{
 "devDependencies": {
 "oxlint": "^1.86.0",
 "oxlint-tsgolint": "npm:tsgolint-rust@0.1.0"
 },
 "overrides": {
 "oxlint-tsgolint": "$oxlint-tsgolint"
 }
}

네이티브 빌드를 사용할 수 없는 환경에서는 Node의 WASI에서 실행하는 WASM 패키지를 쓸 수 있다. 프로젝트 설명에 따르면 Linux와 macOS에서 한 스레드로 실행하며 네이티브 빌드와 같은 출력을 낸다.

json
"oxlint-tsgolint": "npm:@tsgolint-rust/wasm32-wasip1@0.1.0"

이 구현은 TypeScript 7.1.0-dev 기반 ts-rust를 사용한다. 이는 기존 tsgolint에 포함된 TypeScript 7.0보다 몇 달 새 버전이어서, 메시지에 표시되는 일부 타입 문자열의 잘리는 지점이나 진단 내용이 달라질 수 있다. 차이점 설명과 저장소를 참고할 수 있다.