Fastify, Hono, Express, API 라우팅 | Node 백엔드 프레임워크는 언제 갈라질까?
Fastify·Hono·Express를 런타임·JSON 스키마·플러그인·엣지 배포·팀 이전 비용 기준으로 표 비교한다. Node API·REST·TypeScript·미들웨어·OpenAPI·BFF 선택, tRPC·Elysia와의 경계, 카나리 이전 체크리스트와 공식 문서 출처를 개발자·백엔드 관점에서 정리한 vs-comparison 가이드.
Node.js API를 새로 깔 때 Express(Express)만 고르던 시절은 끝났다. 같은 “라우터 + 미들웨어” 그림이어도 Fastify는 스키마·직렬화·플러그인 경계를, Hono는 엣지·멀티 런타임·얇은 코어를, Express는 미들웨어 생태계와 채용 시장 문서를 가져온다.
벤치 숫자 한 장보다 먼저 볼 것은 네 가지다. 런타임(Node 전용 vs 워커), JSON 스키마 검증을 어디에 둘지, 팀 안 Express 경력 비중, 그리고 6개월 뒤 옮길 때의 라우트 이식 비용. 아래 표는 그 조건으로 세 프레임워크를 갈라 둔 선택 가이드다.
조건표로 고르기 | 언제 Fastify, 언제 Hono, 언제 Express
“가장 빠른 것”이 아니라 지금 스택과 실패 비용으로 고른다. 조건만 압축하면 아래와 같다.
신규 서비스 기본값은 팀 런타임으로 갈린다. Node 서버 고정이면 Fastify, 엣지·멀티 런타임이면 Hono, 인수·교육·외주 속도가 1순위면 Express. 엔드포인트 네이밍·에러 포맷은 프레임워크와 별개로 REST 체크리스트를 먼저 맞추는 편이 싸다.
API 프레임워크 선택은 벤치 숫자보다 런타임·스키마·팀 문서로 갈린다
라우팅·미들웨어·플러그인 | 요청이 지나가는 길이 다르다
Express는 app.use 체인에 미들웨어를 쌓는다. 전역 순서가 곧 동작이다. 같은 경로에 인증·로깅·파서를 붙일 때 순서를 바꾸면 버그가 난다. 익숙하면 빠르고, 팀이 커지면 “누가 어디에 뭘 넣었는지”가 문서 밖 지식이 된다. 온보딩 문서에 미들웨어 순서를 표로 박아 두지 않으면 장애 때 추적이 어렵다.
Fastify는 플러그인 단위로 컨텍스트를 가둔다. 라우트 접두사, 훅(onRequest, preHandler), 데코레이터를 플러그인 안에 넣고 바깥 스코프와 분리한다. “이 인증은 이 프리픽스에만” 같은 경계를 코드 구조로 강제하기 쉽다. 처음 익힐 때는 Express보다 개념이 많고, 대신 서비스가 커질수록 모듈 경계가 코드에 남는다.
Hono는 체이닝 미들웨어와 라우트 그룹이 웹 표준 요청·응답 위에 올라간다. Express 문법과 비슷한 부분이 많아 입문 마찰은 낮고, 엣지에서 돌릴 때도 같은 미들웨어 개념을 유지한다. 다만 Node 전용 네이티브 모듈·오래된 Express 미들웨어를 그대로 꽂기는 어렵다. 호환 레이어를 쓰거나 미들웨어를 다시 쓰는 비용을 미리 견적해야 한다.
항목
Express
Fastify
Hono
확장 단위
미들웨어 함수
플러그인 + 훅
미들웨어 + 라우트 그룹
스코프 격리
약함(전역 순서 의존)
강함(encapsulate)
중간(그룹·베이스 경로)
레거시 npm 미들웨어
가장 넓음
Fastify 플러그인 또는 래퍼
Web 표준 호환 위주
에러 처리 습관
next(err) 패턴
setErrorHandler 등
onError·HTTPException 계열
백그라운드 작업·재시도는 프레임워크 밖 큐로 빼는 편이 낫다. API 서버 안에 setTimeout 재시도만 쌓지 말고 BullMQ 작업 큐처럼 워커를 분리하면 프레임워크 교체 때도 비즈니스 잡이 덜 흔들린다.
타입스크립트·스키마 검증 | 입력을 어디서 막을까
세 프레임 모두 TypeScript로 쓸 수 있다. 차이는 “요청 본문·쿼리를 런타임에 어떻게 거르느냐”에 가깝다.
Fastify는 JSON Schema를 라우트 정의에 붙이는 패턴이 공식 문서 중심이다. 스키마가 검증과 응답 직렬화 최적화에 연결된다. Ajv 기반 검증, 응답 스키마로 불필요 필드 제거 같은 흐름이 프로덕션 체크리스트에 잘 올라간다.
Hono는 조드(Zod) 등 외부 검증기·헬퍼와 조합하는 사례가 많다. 라우트가 얇고, 검증 라이브러리 선택을 팀에 맡기는 편이다. 엣지 번들 크기를 의식하면 검증기 번들 무게도 같이 재야 한다.
Express는 검증이 프레임 밖에 있다. express-validator, Zod 미들웨어, 수작업 if 문이 팀마다 갈린다. 유연하지만 API마다 에러 응답 모양이 달라지기 쉽다. 공개 API라면 프레임 선택과 별도로 검증·에러 포맷 표준을 문서에 고정하는 편이 안전하다.
Fastify — 스키마가 붙은 라우트 골격 (개념)
// 공식 문서 패턴 요약 — 프로젝트 버전에 맞게 조정
fastify.post('/orders', {
schema: {
body: {
type: 'object',
required: ['sku', 'qty'],
properties: {
sku: { type: 'string', minLength: 1 },
qty: { type: 'integer', minimum: 1 },
},
},
},
}, async (request, reply) => {
const body = request.body
return { ok: true, sku: body.sku, qty: body.qty }
})
Hono — 라우트 + 조드 검증 조합 예 (개념)
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
const orderSchema = z.object({
sku: z.string().min(1),
qty: z.number().int().positive(),
})
app.post('/orders', zValidator('json', orderSchema), (c) => {
const body = c.req.valid('json')
return c.json({ ok: true, sku: body.sku, qty: body.qty })
})
export default app
Express 쪽은 같은 스키마를 미들웨어로 감싸거나 핸들러 안에서 safeParse를 호출한다. 동작은 같지만, “라우트 정의 = 계약”으로 보이게 만들려면 팀 컨벤션이 필요하다. OpenAPI를 뽑을 때도 Fastify·Hono 쪽이 플러그인·헬퍼 선택지가 비교적 정리돼 있다. REST 리소스 설계 자체는 API 설계 모범 사례를 기준으로 세 프레임 모두 동일하게 적용한다.
입력을 라우트 계약으로 고정하면 에러 포맷과 OpenAPI 문서화가 함께 안정된다
런타임·엣지 | Node 전용인지 워커까지인지
Express와 Fastify의 기본 무대는 Node.js HTTP 서버다. 클러스터·프로세스 매니저·리버스 프록시 뒤에 두는 전통 배포와 잘 맞는다. 네이티브 애드온, 파일 시스템, 오래 유지하는 연결(웹소켓 등)을 전제로 한 서비스에 익숙한 경로다. 사내 인프라가 컨테이너·가상머신 중심이면 이 경로의 운영 글과 장애 사례가 더 많다.
Hono는 처음부터 웹 표준 요청·응답을 중심에 둔다. Cloudflare Workers, Deno Deploy, Bun, Node 어댑터 등 배포 타깃을 바꾸어도 라우트 코드를 크게 바꾸지 않으려는 설계다. 콜드 스타트·번들 크기·CPU 시간 과금이 있는 엣지에서는 이 얇음이 이득이다. 반대로 “Node 전용 드라이버 + 긴 트랜잭션 + 로컬 디스크”가 본업이면 Hono의 이점이 줄어들고, Fastify나 Express 쪽 운영 레시피가 더 풍부하다.
같은 “빠른 JS 서버”라도 Bun만 쓸 계획이면 Elysia처럼 그 런타임에 붙는 프레임이 후보에 오른다. Hono는 그 사이—여러 런타임을 한 팀에서 섞을 때—에 가깝다. 배포 단위를 컨테이너 한 종류로 고정할 계획이면 멀티 런타임 이점을 과대평가하지 않는 것이 좋다. 국내 클라우드 리전·망 분리 정책이 있으면 엣지 진입점과 오리진 API를 나누는 그림부터 그려 두는 편이 안전하다.
성능 표를 읽는 법 | 벤치와 실서비스 사이의 간격
공개 벤치마크는 보통 “인사 응답 + JSON 직렬화”에 가깝다. 실서비스 지연 상위 구간은 DB, 외부 API, 로깅, 인증, 페이로드 크기가 더 크게 좌우한다. 프레임워크 순위를 절대 순위로 외우기보다, 어디가 오버헤드를 줄이도록 설계됐는지만 구분하면 충분하다. 팀 회의 자료에 벤치 숫자만 붙이지 말고, 측정 환경과 미들웨어 개수를 같이 적어 둔다.
관찰 포인트
Express
Fastify
Hono
요청 경로 오버헤드
미들웨어 체인 길이에 민감
라우트 트리·스키마 직렬화 최적화 지향
얇은 코어, 엣지 친화
JSON 입출력
body-parser 등 조합
스키마 연동 직렬화가 강점 영역
런타임·번들에 따라 편차
병목 실체
대부분 DB·네트워크·동기 블로킹 — 프레임 교체만으로 해결 드묾
측정 방법
동일 머신·동일 페이로드·동일 미들웨어 수로 자체 부하 테스트 후 채택
공식·커뮤니티 벤치를 인용할 때는 날짜·커밋·시나리오를 같이 적는다. 숫자만 복사해 “N배 빠르다”로 의사결정 문서를 쓰면 6개월 뒤 재현이 안 된다. 프로덕션에서는 프레임 교체 전에 쿼리 인덱스, 커넥션 풀, 타임아웃, 회로 차단부터 손보는 편이 비용 대비 효과가 큰 경우가 많다. 외부 의존 실패 패턴은 회로 차단기 케이스를 참고한다.
공개 벤치보다 동일 조건 자체 부하 테스트가 프레임 선택 근거가 된다
팀 시나리오 네 가지 | 스타트업·레거시·엣지·BFF
1) 인원 2~5명, Node API 신설, 컨테이너 배포 고정 Fastify를 기본으로 두고 라우트마다 입출력 스키마를 붙인다. 플러그인으로 auth·db 클라이언트를 나눈다. 채용 풀이 Express 위주여도 “스키마 있는 라우트” 컨벤션만 문서 한 장이면 온보딩이 된다.
2) Express 5년차 모놀리스, 분기마다 핫픽스 전면 교체하지 않는다. 신규 도메인만 Fastify/Hono 마이크로서비스로 빼거나, 게이트웨이 뒤에서 점진 이전한다. passport·세션·레거시 미들웨어 호환 비용이 성능 이득을 삼키는지 먼저 견적낸다.
3) 엣지에서 인증 게이트·경량 BFF Hono. 워커 CPU 시간·번들 한도가 있으면 “두꺼운 Express 앱을 엣지에 올리기”보다 얇은 라우터가 맞다. 무거운 비즈니스는 오리진 Node(Fastify)로 넘기는 이단 구조가 흔하다.
4) Next.js 같은 풀스택과 타입 공유가 최우선 순수 REST 공개 API가 아니면 tRPC 또는 서버 액션 경계를 먼저 검토한다. 외부 클라이언트·모바일·파트너 연동이 있으면 REST + OpenAPI 쪽이 장기적으로 문서 비용이 낮다. 이때 서버 구현체는 Fastify/Hono 중 배포 타깃으로 고른다.
이전·병행 체크리스트 | 바꾸기 전에 채울 항목
라우트 인벤토리: 공개/내부, 인증 필요 여부, 파일 업로드·스트리밍 여부
미들웨어 목록: Express 전용 패키지 중 Hono/Fastify 대체 가능 여부
에러·로깅 포맷: 클라이언트·관측 스택이 의존하는 필드명 고정 여부
세션·쿠키·CORS: 엣지로 옮기면 도메인·SameSite 정책이 깨지는지
테스트: 슈퍼테스트 계열 vs app.request 주입 방식 차이, CI 실행 시간
롤백: 트래픽 일부만 새 프레임으로 보내는 게이트웨이·카나리 경로
문서: OpenAPI 생성 파이프라인이 새 프레임에서 재현 가능한지
웹훅·재시도·멱등 키가 있는 엔드포인트는 프레임과 무관하게 계약이 먼저다. 콜백 폭주 방지는 웹훅 멱등·재시도 순서를 그대로 이전 체크리스트에 넣는다. 배포 회귀는 카나리·헬스체크 런북과 붙인다.
아니다. 레거시 미들웨어·외주·교육 자료·채용 풀이 Express에 몰려 있으면 합리적이다. 다만 JSON 스키마·플러그인 격리를 기본값으로 두고 싶다면 Fastify가, 엣지 배포를 전제한다면 Hono가 더 맞는 경우가 많다. “틀린 선택”보다 “6개월 뒤 이전 비용”을 견적하는 편이 낫다.
Fastify와 Hono 중 하나만 고른다면?
배포 타깃이 Node 컨테이너 한 종류면 Fastify, Workers·Bun·Deno를 섞거나 옮길 계획이 있으면 Hono. 둘 다 TypeScript REST를 잘 한다. 차이는 스키마·플러그인 문화(Fastify) vs 멀티 런타임·얇은 코어(Hono)에 가깝다.
공개 벤치에서 느린 프레임은 프로덕션에서 무조건 불리한가?
아니다. 실서비스 지연의 대부분은 DB·외부 API·동기 블로킹에서 나온다. Hello World 순위는 “프레임 오버헤드 성향” 참고용이다. 동일 미들웨어·동일 페이로드로 자체 부하 테스트를 돌린 뒤 채택하는 것이 안전하다.
Express 앱을 Fastify로 한 번에 옮기는 게 맞나?
라우트·미들웨어가 많으면 한 번에 옮기기보다 도메인 단위 분리나 게이트웨이 병행이 안전하다. passport·세션·파일 업로드·커스텀 파서 호환을 먼저 목록화하고, 공개 API 계약(상태코드·에러 바디)을 고정한 뒤 트래픽을 나눠 옮긴다.
tRPC를 쓰면 이 비교가 필요 없어지나?
풀스택 TypeScript 내부 API에는 tRPC가 잘 맞는다. 파트너·모바일·다중 언어 클라이언트·공개 REST가 있으면 OpenAPI 가능한 HTTP 서버(Express/Fastify/Hono)가 여전히 필요하다. tRPC 서버 어댑터 아래에도 결국 HTTP 레이어가 있으므로, 엣지 배포 여부는 따로 결정한다.
검증 라이브러리는 조드만 쓰면 되나?
조드가 흔하지만 필수는 아니다. Fastify는 JSON Schema를 기본으로 쓰고, Hono·Express는 조드·Valibot 등을 붙이는 식이다. 팀 표준 하나와 에러 응답 포맷만 통일하면 된다. 번들 예산이 빡센 엣지에서는 검증기 용량도 같이 잰다.