"런타임을 고르는 일과 타입 시스템을 고르는 일은 같지 않아."
TypeScript 소스를 실행하는 길
Node에서는 빌드된 JavaScript를 실행하거나 tsx 같은 개발 도구로 TypeScript 소스를 변환해 실행할 수 있어. Bun은 TypeScript 파일을 직접 실행하는 흐름을 제공해. 어느 쪽도 실행 명령만으로 프로젝트 전체 타입 검사가 끝났다고 가정하면 안 돼.
개발 편의와 프로덕션 경로가 다르면 모듈 해석, 소스맵, 환경 변수 로딩 차이를 확인해야 해. 출시 환경에서 실제로 쓰는 명령을 CI와 스테이징에서 반복해.
프레임워크 타입은 입력 검증이 아니다
Express, Fastify, Hono 같은 서버 프레임워크는 요청과 응답에 TypeScript 타입을 연결할 수 있어. 하지만 HTTP 본문과 쿼리는 외부 값이므로 제네릭에 Body를 적는 것만으로 검증되지 않아. 스키마 검증 결과에서 타입이 파생되게 만들면 중복 계약을 줄일 수 있어.
오류 처리 미들웨어와 인증 정보 보강도 프레임워크의 실제 런타임 순서와 타입 선언이 맞아야 해. 전역 선언 보강만 하고 미들웨어를 빠뜨리면 타입에는 있는 값이 실행 중에 사라져.
호환성과 운영으로 선택하기
속도 수치 하나보다 필요한 패키지, 네이티브 모듈, 배포 플랫폼, 디버깅과 관측 도구를 기준으로 런타임을 골라. Node 호환이라는 넓은 표현 대신 애플리케이션의 대표 경로를 직접 시험해.
런타임 전용 API를 얇은 어댑터 뒤에 두면 선택을 바꿀 때 영향이 줄어. 다만 추상화가 실제 교체 가능성을 만들지 못하고 두 런타임의 최소 공통분모만 강요한다면 오히려 복잡해질 수 있어.
Express는 @types/express가 필요하지만 Fastify와 Hono는 자체 타입을 제공해. 새 백엔드 TypeScript에서는 속도와 타입 경험을 중시하면 Bun+Hono를, 기존 생태계 호환성이 중요하면 Node+Express를 기본 선택으로 볼 수 있어.