TypeScript 컴파일러가 Go로 다시 쓰여서 타입 체크가 10배 빨라졌다
tsc는 왜 느렸나, Go로 옮기니 왜 빨라졌나
#TypeScript #빌드 #Go #프론트엔드
블로그 프론트가 TypeScript 4.9에 멈춰 있었다. 프로젝트가 커지니까 에디터에서 빨간 줄 뜨는 게 굼떠지고, 타입 체크 한 번 도는 게 답답했다. 그러다 TypeScript 7이 컴파일러를 통째로 Go로 다시 썼고, 10배 빨라졌다 는 걸 보고 바로 올렸다. 이 글에선 기존 tsc가 왜 느렸는지, Go로 옮기니까 왜 빨라졌는지를 정리해본다. 기존 컴파일러는 자기 자신으로 짜여 있었다 의외로 모르는 사람이 많은데, 그동안 TypeScript 컴파일러(tsc)는 TypeScript로 짜여 있었다 . 즉 결국 자바스크립트로 도는 프로그램이었다. 컴파일러가 자바스크립트로 돌면 두 가지 한계를 그대로 안고 간다. 1. 단일 스레드 — 자바스크립트는 기본적으로 한 번에 한 줄씩 돈다. CPU 코어가 여러 개여도 한 개만 쓴다. 2. GC 멈춤 — 메모리를 자동으로 치우는 가비지 컬렉션이 중간중간 돌면서 멈춘다. 타입 체크는 코드 전체의 타입 관계를 그래프로 그려서 끝없이 따라다니는 작업이라, 위 두 한계에 정통으로 걸린다. 프로젝트가 커질수록 기하급수로 느려졌던 이유다. 그래서 Go로 다시 썼다 — 왜 빨라졌나 TypeScript 7은 컴파일러를 Go 로 처음부터 다시 짰다. 빨라진 이유는 두 개다. 1. 네이티브로 컴파일된다 — Go는 기계어로 떨어진다. 자바스크립트처럼 런타임이 한 줄씩 해석하는 게 아니라, CPU가 바로 먹는 코드로 돈다. 2. 공유 메모리 병렬이 된다 — Go는 여러 코어를 진짜로 동시에 굴린다. 자바스크립트가 못 하던 바로 그것. 타입 그래프를 여러 갈래로 나눠 동시에 훑을 수 있다. 숫자로 보면 확실하다. VSCode 코드베이스(150만 줄)가 89초 → 8.74초, 10.2배 빨라졌다. 내 블로그처럼 작은 프로젝트도 에디터 반응이 확 가벼워졌다. 근데 왜 Rust가 아니라 Go였나 Vite는 Rust로 갔는데(지난 글) TypeScript는 왜 Go냐는 궁금증이 들었다. 이유가 재밌다. 기존 tsc는 그래프를 타고 돌아다니는 구조 에 GC를 적극적으로 쓰는 코드였는데, Go가 그 구조랑 메모리 모델이 잘 맞아서 거의 1:1로 포팅 하기 쉬웠다고 한다. 동작을 그대로 옮기면서 속도만 올리려면 Go가 합리적인 선택이었던 거다. 새 컴파일러는 tsgo 라는 실행 파일로 미리 써볼 수 있었고, 2026년 초에 정식(7.0)으로 안정화됐다. Bloomberg, Figma, Google, Slack, Vercel 같은 데가 미리 프로덕션에서 굴려봤다고 한다. 4.9에서 올릴 때 주의 버전 갭이 커서(4.9 → 7) 그동안 느슨하게 넘어가던 타입 몇 개가 새로 걸렸다. 근데 이건 오히려 그동안 숨어 있던 허점이 드러난 거라, 잡고 나니 코드가 더 단단해졌다. 속도 때문에 올렸다가 타입 안정성까지 챙긴 셈이다. 정리하면 지난 Vite 글에서 "빌드가 느린 건 도구가 아니라 언어의 한계였다"고 했는데, TypeScript에서 두 번째로 증명 됐다. tsc가 느렸던 건 자바스크립트로 짜여서였고, Go로 옮기니 10배가 됐다. Vite는 Rust, TypeScript는 Go — 자바스크립트 도구 체인이 통째로 네이티브로 옮겨가는 흐름의 한가운데다. 타입 체크가 굼떠서 답답했다면, TypeScript 7로 올려보는 걸 권한다. 큰 프로젝트일수록 차이가 극적이고, 작은 프로젝트도 에디터가 가벼워지는 게 바로 느껴진다.