Hono.js: o framework web minimalista que está crescendo no ecossistema Bun

1. O que é Hono.js e por que ele está ganhando destaque

Hono.js é um framework web minimalista e ultrarrápido criado por Yusuke Wada, projetado para ambientes JavaScript modernos como Bun, Deno, Node.js e Cloudflare Workers. Sua filosofia central é oferecer o mínimo necessário para construir aplicações web eficientes, sem o peso de abstrações desnecessárias.

Diferentemente do Express.js, que carrega décadas de compatibilidade retroativa, e do Fastify, que prioriza plugins e schema-based validation, o Hono.js foca em simplicidade extrema e desempenho nativo. Em benchmarks comparativos, Hono.js supera Express em até 10x em requisições por segundo, especialmente quando executado no runtime Bun.

A integração nativa com Bun é um dos principais motivos de seu crescimento. Bun oferece um runtime JavaScript ultrarrápido com APIs nativas para HTTP, e Hono.js tira proveito disso sem abstrações desnecessárias. Além disso, seu suporte multiplataforma permite que o mesmo código rode em ambientes serverless, edge computing e servidores tradicionais.

2. Primeiros passos com Hono.js no ecossistema Bun

Para começar, certifique-se de ter o Bun instalado. Crie um novo projeto:

bun init -y
bun add hono

A estrutura básica de um aplicativo "Hello World" com Hono.js e Bun:

import { Hono } from 'hono'

const app = new Hono()

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

export default app

Para executar, use o servidor embutido do Bun:

bun run --watch index.ts

A configuração de rotas simples segue o padrão familiar de frameworks web. O middleware padrão pode ser adicionado globalmente ou por rota:

import { Hono } from 'hono'
import { cors } from 'hono/cors'

const app = new Hono()

app.use('*', cors())

app.get('/api', (c) => c.json({ message: 'API funcionando' }))

3. Roteamento e manipulação de requisições

O sistema de roteamento do Hono.js é baseado em uma estrutura de trie (trie tree), o que garante performance excepcional mesmo com centenas de rotas. Diferente do Express, que usa expressões regulares complexas, o Hono.js otimiza a busca de rotas para O(n) no pior caso.

Exemplo de parâmetros de rota:

app.get('/users/:id', (c) => {
  const id = c.req.param('id')
  return c.json({ userId: id })
})

Query strings são acessadas diretamente:

app.get('/search', (c) => {
  const query = c.req.query('q')
  const page = c.req.query('page') || '1'
  return c.json({ query, page })
})

Para organização modular, use grupos de rotas:

import { Hono } from 'hono'

const users = new Hono()

users.get('/', (c) => c.json([{ id: 1, name: 'Alice' }]))
users.post('/', (c) => c.json({ created: true }))
users.get('/:id', (c) => c.json({ id: c.req.param('id') }))

const app = new Hono()
app.route('/users', users)

4. Middleware e extensibilidade

Hono.js oferece middleware embutido essencial:

import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
import { etag } from 'hono/etag'

const app = new Hono()

app.use('*', logger())
app.use('*', cors())
app.use('*', etag())

Para middleware customizado de autenticação:

import { Hono } from 'hono'

const authMiddleware = async (c, next) => {
  const token = c.req.header('Authorization')
  if (!token || token !== 'Bearer meu-token-secreto') {
    return c.json({ error: 'Não autorizado' }, 401)
  }
  await next()
}

app.get('/protected', authMiddleware, (c) => {
  return c.json({ secret: 'dados protegidos' })
})

Integração com Zod para validação:

import { z } from 'zod'

const userSchema = z.object({
  name: z.string().min(3),
  email: z.string().email()
})

app.post('/users', async (c) => {
  const body = await c.req.json()
  const result = userSchema.safeParse(body)
  if (!result.success) {
    return c.json({ errors: result.error.errors }, 400)
  }
  return c.json({ created: result.data })
})

5. Tratamento de erros e respostas HTTP

O tratamento centralizado de erros é feito com app.onError():

app.onError((err, c) => {
  console.error(err.message)
  return c.json({
    error: 'Erro interno do servidor',
    details: err.message
  }, 500)
})

Respostas padronizadas em diferentes formatos:

app.get('/json', (c) => c.json({ status: 'ok' }))
app.get('/text', (c) => c.text('Resposta simples'))
app.get('/html', (c) => c.html('<h1>Página HTML</h1>'))

Códigos de status personalizados:

app.post('/items', async (c) => {
  const item = await c.req.json()
  if (!item.name) {
    return c.json({ error: 'Nome é obrigatório' }, 400)
  }
  return c.json({ created: item }, 201)
})

6. Desempenho e deploy em produção

Benchmarks recentes mostram que Hono.js no Bun processa aproximadamente 180.000 requisições/segundo, contra 45.000 do Express e 95.000 do Fastify. Esse desempenho vem da combinação do runtime Bun com o roteamento trie do Hono.js.

Para deploy em produção, o servidor embutido do Bun é suficiente:

bun run index.ts --port 3000

Para Cloudflare Workers, a configuração é mínima:

import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Worker funcionando'))

export default app

Dicas de otimização:

  • Use compressão com hono/compress para respostas grandes
  • Implemente caching com headers Cache-Control
  • Para conexões persistentes, confie no gerenciamento automático do Bun

7. Casos de uso e comunidade

Hono.js é ideal para:

  • APIs REST leves e rápidas
  • Microserviços em arquiteturas serverless
  • Aplicações edge computing (Cloudflare Workers, Deno Deploy)
  • Prototipagem rápida de backends

Exemplo prático: API de tarefas (CRUD) com Bun e Hono:

import { Hono } from 'hono'

const app = new Hono()
let tasks = []
let idCounter = 1

app.get('/tasks', (c) => c.json(tasks))

app.post('/tasks', async (c) => {
  const { title } = await c.req.json()
  const task = { id: idCounter++, title, completed: false }
  tasks.push(task)
  return c.json(task, 201)
})

app.put('/tasks/:id', async (c) => {
  const id = parseInt(c.req.param('id'))
  const { title, completed } = await c.req.json()
  const task = tasks.find(t => t.id === id)
  if (!task) return c.json({ error: 'Tarefa não encontrada' }, 404)
  if (title) task.title = title
  if (completed !== undefined) task.completed = completed
  return c.json(task)
})

app.delete('/tasks/:id', (c) => {
  const id = parseInt(c.req.param('id'))
  tasks = tasks.filter(t => t.id !== id)
  return c.json({ deleted: true })
})

export default app

A comunidade Hono.js está crescendo rapidamente, com plugins oficiais para autenticação, WebSockets e integração com bancos de dados. A documentação oficial é clara e bem estruturada, e o repositório no GitHub já ultrapassou 15.000 estrelas.

Referências