Devlery
Blog/Hono

Hono: 어디서든 돌아가는 초경량 웹 프레임워크

Express를 대체할 차세대 웹 프레임워크 Hono의 설치부터 라우팅, 미들웨어, 다양한 런타임 배포까지 핵심 기능을 알아봅니다.

Node.js 백엔드를 구축할 때 대부분의 개발자가 가장 먼저 떠올리는 프레임워크는 Express다. 10년 넘게 사실상의 표준 역할을 해왔으니 당연한 일이다. 하지만 Cloudflare Workers, Deno, Bun 같은 새로운 런타임이 등장하면서, Express만으로는 커버하기 어려운 영역이 생겼다.

Hono는 이 문제를 정면으로 해결한다. 이름은 일본어로 "불꽃(炎)"이라는 뜻으로, 이름값을 하듯 빠르고 가볍다.

Hono가 뭔가요?

Hono는 Web Standards 위에 구축된 초경량 웹 프레임워크다. 가장 큰 특징은 하나의 코드로 거의 모든 JavaScript 런타임에서 동작한다 는 점이다.

  • Cloudflare Workers
  • Deno
  • Bun
  • Node.js
  • AWS Lambda
  • Vercel
  • Netlify

Express가 Node.js에 종속되어 있는 것과 달리, Hono는 표준 Web API(Request, Response, fetch)를 기반으로 만들어졌기 때문에 런타임을 가리지 않는다.

설치 및 시작

프로젝트를 새로 만들 때는 공식 CLI를 사용하면 편하다.

npm create hono@latest my-app

실행하면 어떤 런타임용 템플릿을 사용할지 선택할 수 있다. Node.js, Cloudflare Workers, Bun 등 다양한 옵션이 나온다.

기존 프로젝트에 추가하고 싶다면 직접 설치하면 된다.

npm install hono

기본 사용법

Express를 써본 적이 있다면 매우 익숙하게 느껴질 것이다.

import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.text('Hello, Hono!')
})

app.get('/api/posts', (c) => {
  return c.json({ posts: [] })
})

export default app

c는 Context 객체로, 요청 정보를 읽고 응답을 생성하는 역할을 한다. c.text(), c.json(), c.html() 등 응답 타입별 헬퍼가 준비되어 있어서 직관적이다.

라우팅

Hono의 라우터는 JavaScript 세계에서 가장 빠르다고 알려져 있다. 내부적으로 RegExpRouter라는 최적화된 라우터를 사용한다.

// 경로 파라미터
app.get('/posts/:id', (c) => {
  const id = c.req.param('id')
  return c.json({ id })
})

// 그룹 라우팅
const api = new Hono()
api.get('/users', (c) => c.json({ users: [] }))
api.get('/posts', (c) => c.json({ posts: [] }))

app.route('/api', api)

그룹 라우팅을 지원하기 때문에 대규모 API를 구조적으로 관리할 수 있다.

미들웨어

Hono는 배터리가 포함된 프레임워크다. 자주 쓰는 미들웨어가 내장되어 있어서 별도 패키지를 설치할 필요가 없다.

import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
import { bearerAuth } from 'hono/bearer-auth'

const app = new Hono()

app.use('*', logger())
app.use('/api/*', cors())
app.use('/admin/*', bearerAuth({ token: 'my-secret' }))

CORS, 로깅, 인증, 캐싱, ETag, 압축 등 실무에서 자주 필요한 것들이 모두 내장되어 있다.

TypeScript 지원

Hono의 타입 지원은 단순한 타입 정의 수준을 넘어선다. 라우트 정의에서 요청/응답 타입이 자동으로 추론된다.

const route = app.get('/posts/:id', (c) => {
  const id = c.req.param('id') // string으로 자동 추론
  return c.json({ id, title: 'Hello' })
})

// 클라이언트에서 타입 안전한 API 호출
import { hc } from 'hono/client'

const client = hc<typeof route>('http://localhost:8787')
const res = await client.posts[':id'].$get({ param: { id: '1' } })
const data = await res.json() // { id: string, title: string }

hono/client를 사용하면 별도의 API 스키마 정의 없이도 서버와 클라이언트 간 타입 안전성을 확보할 수 있다. tRPC와 비슷한 개발 경험을 프레임워크 자체에서 제공하는 셈이다.

Express와 비교하면?

항목ExpressHono
번들 크기~200KB+ 의존성 포함~14KB (hono/tiny)
런타임 지원Node.js거의 모든 JS 런타임
TypeScript별도 @types 필요네이티브 지원
미들웨어서드파티 의존내장 미들웨어 제공
타입 안전 클라이언트없음hono/client 내장

Express가 나쁜 프레임워크라는 뜻은 아니다. 다만 2026년 시점에서 새로운 프로젝트를 시작한다면, 특히 엣지 환경이나 서버리스 배포를 고려하고 있다면 Hono가 더 적합한 선택일 수 있다.

마무리

Hono는 GitHub 스타 수가 4만을 넘었고, 생태계도 빠르게 성장하고 있다. 풀스택 메타 프레임워크인 HonoX도 등장했다.

Express를 잘 쓰고 있다면 당장 바꿀 필요는 없다. 하지만 새 프로젝트를 시작하거나, 엣지 환경에 API를 배포해야 한다면 한 번쯤 써볼 가치가 있다. Web Standards 기반이라 나중에 런타임을 바꾸더라도 코드를 그대로 가져갈 수 있으니까.