Programação & Dev

Hono.js: O Framework Web Mais Rápido que Você Provavelmente Ainda Não Usa

Express tem 13 anos. Hono tem zero dependências, roda em qualquer runtime e processa 4x mais requisições. Entenda por que o ecossistema JavaScript está migrando.

Hono.js: O Framework Web Mais Rápido que Você Provavelmente Ainda Não Usa

Express foi lançado em 2010. Na época, não existia TypeScript como linguagem popular, edge computing era ficção científica e Cloudflare Workers nem estava no horizonte.

O ecossistema JavaScript de 2026 é outro. Temos Bun, Deno, Cloudflare Workers, AWS Lambda Edge — cada um com suas particularidades de runtime. E temos o Hono: um framework construído para esse mundo.

2.8 milhões de downloads semanais no final de 2025 — crescimento de 340% em um ano. Não é hype. É adoção real de times que testaram e ficaram.

Bundle size
12kB
zero dependências externas
Cloudflare Workers
100k+
requisições por segundo
vs Express
4-5×
mais rápido no Node.js

O que é o Hono

Hono (炎) significa chama em japonês. Foi criado por Yusuke Wada com um objetivo específico: um framework web construído sobre Web Standards que rode em qualquer runtime JavaScript — sem adaptações, sem workarounds.

A diferença central em relação ao Express: Hono usa as APIs nativas da plataforma web — Request, Response, fetch. Express usa o módulo http do Node.js, que não existe em outros runtimes. Essa decisão de design é o que torna o Hono genuinamente multi-runtime.

Hono Web Standards Cloudflare Workers AWS Lambda Node.js Bun Deno Vercel Edge
Diagrama — Hono roda em qualquer runtime JavaScript

Começando do zero

A API do Hono vai parecer familiar se você já usou Express. A diferença aparece nos detalhes — e nos detalhes está tudo.

JS
# Para Node.jsnpm create hono@latest meu-app# Selecione: nodejs# Para Cloudflare Workersnpm create cloudflare@latest meu-app -- --template=hono# Para Bunbun create hono meu-app
JS
import { Hono } from 'hono'const app = new Hono()app.get('/', (c) => c.text('Hono!'))app.get('/json', (c) => c.json({ message: 'olá' }))app.post('/echo', async (c) => {  const body = await c.req.json()  return c.json(body)})export default app

Routing e agrupamento de rotas

O sistema de rotas do Hono usa um router RegExpRouter baseado em trie — sem loops lineares. É o que garante a performance mesmo com centenas de rotas registradas.

JS
import { Hono } from 'hono'const app = new Hono()// Parâmetros de rotaapp.get('/posts/:id', (c) => {  const id = c.req.param('id')  return c.json({ id })})// Query stringsapp.get('/search', (c) => {  const q = c.req.query('q')  const page = c.req.query('page') ?? '1'  return c.json({ q, page })})// Agrupamento com basePathconst api = new Hono().basePath('/api')// Sub-routers por recursoconst users = new Hono()users.get('/', (c) => c.json([]))users.post('/', async (c) => {  const body = await c.req.json()  return c.json(body, 201)})users.get('/:id', (c) => c.json({ id: c.req.param('id') }))// Montar no app principalapi.route('/users', users)export default api

Middleware

Hono tem middleware built-in para os casos mais comuns — sem precisar instalar pacotes externos. CORS, logger, autenticação básica, cache, compressão — tudo disponível no pacote principal.

JS
import { Hono } from 'hono'import { cors } from 'hono/cors'import { logger } from 'hono/logger'import { bearerAuth } from 'hono/bearer-auth'import { cache } from 'hono/cache'const app = new Hono()// Middleware globalapp.use('*', logger())app.use('*', cors({  origin: ['https://meusite.com', 'http://localhost:3000'],  allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],}))// Middleware por rotaconst token = 'meu-token-secreto'app.use('/admin/*', bearerAuth({ token }))// Cache em Cloudflare Workersapp.use('/static/*', cache({  cacheName: 'static-assets',  cacheControl: 'max-age=3600',}))// Middleware customizadoapp.use('*', async (c, next) => {  const start = Date.now()  await next()  const ms = Date.now() - start  c.header('X-Response-Time', `${ms}ms`)})app.get('/', (c) => c.text('OK'))export default app

Validação com Zod — o diferencial real

A integração com Zod é onde o Hono mostra a diferença de experiência de desenvolvimento. Você define o schema uma vez e recebe validação automática do request, parsing e inferência de tipos TypeScript — tudo junto.

JS
import { Hono } from 'hono'import { z } from 'zod'import { zValidator } from '@hono/zod-validator'const app = new Hono()// Schema de criação de usuárioconst criarUsuarioSchema = z.object({  nome: z.string().min(2).max(100),  email: z.string().email(),  idade: z.number().int().min(18).optional(),})// Schema de query paramsconst paginacaoSchema = z.object({  pagina: z.coerce.number().int().positive().default(1),  limite: z.coerce.number().int().min(1).max(100).default(20),})app.post(  '/users',  zValidator('json', criarUsuarioSchema),  (c) => {    const { nome, email, idade } = c.req.valid('json')    // nome, email, idade são totalmente tipados aqui    // TypeScript sabe exatamente o que são    return c.json({ id: 1, nome, email, idade }, 201)  })app.get(  '/users',  zValidator('query', paginacaoSchema),  (c) => {    const { pagina, limite } = c.req.valid('query')    // pagina e limite já são numbers, não strings    return c.json({ pagina, limite, total: 0, dados: [] })  })export default app

RPC Client — type safety end-to-end

Esse é o feature que mais surpreende quem vem do Express. O Hono tem um cliente RPC built-in que gera um cliente tipado para chamar as rotas da API diretamente do frontend — sem tRPC, sem geração de código, sem configuração extra.

JS
// server.ts — exporta o tipo das rotasimport { Hono } from 'hono'import { z } from 'zod'import { zValidator } from '@hono/zod-validator'const app = new Hono()const route = app  .get('/api/posts', (c) => c.json([{ id: 1, titulo: 'Olá' }]))  .post(    '/api/posts',    zValidator('json', z.object({ titulo: z.string() })),    async (c) => {      const { titulo } = c.req.valid('json')      return c.json({ id: 2, titulo }, 201)    }  )export type AppType = typeof routeexport default app
JS
// client.ts — frontend com type safety completoimport { hc } from 'hono/client'import type { AppType } from './server'const client = hc<AppType>('http://localhost:8787')// TypeScript sabe o tipo de retorno de cada rotaconst posts = await client.api.posts.$get()const data = await posts.json()// data é tipado como { id: number; titulo: string }[]// Erros de compilação se o payload estiver erradoconst novo = await client.api.posts.$post({  json: { titulo: 'Novo Post' }, // TypeScript valida aqui})
Frontend hc<AppType>(url) client.api.posts.$get() Hono Server export type AppType = typeof route TypeScript valida payload infere tipo de retorno HTTP tipos
Diagrama — Como o RPC Client funciona

JSX e SSR nativo

O Hono suporta JSX nativamente para renderização server-side — sem precisar de React, sem configuração de bundler. É útil para páginas simples, emails transacionais ou qualquer HTML dinâmico.

JS
// app.tsximport { Hono } from 'hono'import type { FC } from 'hono/jsx'const app = new Hono()const Layout: FC = ({ children }) => (  <html lang="pt-BR">    <head>      <meta charset="UTF-8" />      <title>Meu Site</title>    </head>    <body>{children}</body>  </html>)const PostCard: FC<{ titulo: string; resumo: string }> = ({ titulo, resumo }) => (  <article>    <h2>{titulo}</h2>    <p>{resumo}</p>  </article>)app.get('/posts', (c) => {  const posts = [    { titulo: 'Post 1', resumo: 'Resumo 1' },    { titulo: 'Post 2', resumo: 'Resumo 2' },  ]  return c.html(    <Layout>      <h1>Blog</h1>      {posts.map((p) => <PostCard {...p} />)}    </Layout>  )})export default app

Deploy: a mesma aplicação, runtimes diferentes

A portabilidade é a vantagem estratégica mais importante do Hono. O mesmo código de aplicação roda em qualquer runtime — só o adapter muda.

Node.js

import { serve } from '@hono/node-server' import app from './app' serve({ fetch: app.fetch, port: 3000, }) // package.json // "start": "node dist/server.js"

Cloudflare Workers

import app from './app' // Cloudflare Workers usa // o export default diretamente export default app // wrangler.toml // name = "meu-app" // main = "src/index.ts"

Performance: o que os benchmarks dizem

O Express usa o módulo http do Node.js com processamento de middleware síncrono acumulado em 13 anos. O Hono é async nativo, usa a Fetch API internamente e tem um router radix trie otimizado. Menos trabalho por requisição.

Requisições / segundo (maior = melhor) Hono (Bun) ~850k req/s Hono (Cloudflare Workers) ~100k req/s Hono (Node.js) ~350k req/s Express ~80k req/s
Diagrama — Requisições por segundo (benchmark comparativo)

Quando usar e quando não usar

Hono não é bala de prata. A escolha entre ele e o Express depende do contexto.

✅ Use Hono quando

Projeto novo (greenfield) Deploy em edge (Cloudflare Workers) Precisa de multi-runtime (Node + Bun + Deno) TypeScript é prioridade Bundle size importa API gateway ou proxy de performance Time pequeno, sem legado Express

⚠️ Fique no Express quando

Codebase legado com 50+ middlewares Express Time já treinado e produtivo em Express Depende de bibliotecas Express-específicas Migração não justifica o custo Não há planos de edge deployment

Express não vai desaparecer. Ele sustenta milhões de aplicações em produção e vai continuar sendo mantido.

Mas o próximo projeto não precisa começar em 2010.