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.

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.
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.
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.
# 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-appimport { 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 appRouting 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.
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 apiMiddleware
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.
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 appValidaçã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.
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 appRPC 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.
// 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// 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})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.
// 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 appDeploy: 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.
import { serve } from '@hono/node-server' import app from './app' serve({ fetch: app.fetch, port: 3000, }) // package.json // "start": "node dist/server.js"
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.
Quando usar e quando não usar
Hono não é bala de prata. A escolha entre ele e o Express depende do contexto.
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
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.


