Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Hono no Node.js: Guia Prático

Atualizado em: 1 de setembro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

Usar Hono no Node.js permite criar APIs leves com uma interface baseada em Web Standards. O mesmo estilo de código pode rodar em Node.js, runtimes edge, serverless, Bun e Deno, desde que as dependências e integrações sejam compatíveis.

Hono oferece roteamento, middleware, validação, RPC tipado, CORS, JWT, secure headers, streaming e helpers. A portabilidade é uma vantagem, mas exige evitar APIs específicas da plataforma quando o objetivo é executar em vários runtimes. Também é necessário configurar body limits, autenticação, autorização, timeouts e shutdown para produção.

Neste guia, você aprenderá a instalar Hono no Node.js, criar rotas e middleware, trabalhar com context, validar entradas, integrar serviços, proteger APIs, fazer streaming, testar e preparar o deploy.

O que é Hono?

Hono é um framework web pequeno e baseado em padrões da Web. A documentação oficial do Hono apresenta suporte a Node.js e outros runtimes, middleware e RPC. A documentação da MDN sobre Request descreve uma das interfaces utilizadas pelo framework.

Quando usar?

  • APIs leves;
  • aplicações edge;
  • serverless;
  • proxies;
  • BFFs;
  • serviços multi-runtime;
  • projetos TypeScript;
  • bibliotecas que expõem HTTP.

Quando avaliar outra opção?

  • ecossistema depende de middleware Express específico;
  • aplicação usa módulos nativos incompatíveis com edge;
  • equipe precisa das convenções extensas do NestJS;
  • plugins do Fastify são essenciais;
  • o runtime alvo exige integração não suportada.

Compare com Fastify com Node.js e NestJS no Node.js.

Criando um projeto

npm create hono@latest

Selecione o template Node.js ou configure manualmente.

Instalação manual

npm install hono @hono/node-server

Servidor básico

import { Hono } from 'hono';
import { serve } from '@hono/node-server';

const app = new Hono();

app.get('/', c => c.json({
  message: 'Hono no Node.js'
}));

serve({
  fetch: app.fetch,
  port: Number(process.env.PORT || 3000)
});

O adapter conecta o modelo Fetch do Hono ao servidor Node.js.

Context

O objeto c fornece request, response, variáveis, headers e helpers:

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

Query parameters

const search = c.req.query('search');
const limit = Number(c.req.query('limit') || 20);

Valide e limite valores. Converter para Number não garante inteiro, intervalo ou ausência de NaN.

Body JSON

const body = await c.req.json();

O valor é desconhecido em runtime. Use schema antes de acessar campos.

Roteamento

app.get('/projects', listProjects);
app.post('/projects', createProject);
app.get('/projects/:id', getProject);
app.patch('/projects/:id', updateProject);
app.delete('/projects/:id', deleteProject);

Organize handlers por domínio, não em um único arquivo.

Sub-apps

const projects = new Hono();
projects.get('/', listProjects);
projects.post('/', createProject);

app.route('/projects', projects);

Sub-apps ajudam a separar módulos e aplicar middleware específico.

Middleware

app.use('*', async (c, next) => {
  const startedAt = performance.now();
  await next();

  logger.info({
    method: c.req.method,
    path: c.req.routePath,
    status: c.res.status,
    durationMs: performance.now() - startedAt
  }, 'Requisição Hono');
});

Chame await next() para executar o restante da cadeia.

Request ID

Use o middleware oficial ou gere um UUID validando o header recebido. Retorne o ID na resposta e inclua nos logs.

Context variables

app.use('*', async (c, next) => {
  c.set('requestId', crypto.randomUUID());
  await next();
});

Tipagem das variables pode ser declarada no generic do Hono.

Context tipado

type Variables = {
  requestId: string;
  auth: AuthContext;
};

const app = new Hono<{ Variables: Variables }>();

Autenticação

const authenticate = createMiddleware(async (c, next) => {
  const auth = await authService.authenticate(
    c.req.header('authorization')
  );

  if (!auth) {
    return c.json({
      code: 'UNAUTHORIZED',
      message: 'Autenticação necessária'
    }, 401);
  }

  c.set('auth', auth);
  await next();
});

Para tokens, consulte JWT Seguro no Node.js.

Middleware JWT

Hono possui middleware JWT, mas configure algoritmo, issuer, audience e chave corretamente. Não aceite configuração padrão sem entender as claims.

Autorização

function requirePermission(permission) {
  return createMiddleware(async (c, next) => {
    const auth = c.get('auth');

    if (!auth.permissions.includes(permission)) {
      return c.json({ code: 'FORBIDDEN' }, 403);
    }

    await next();
  });
}

O handler ainda deve validar tenant e ownership do recurso. Consulte RBAC no Node.js e ABAC no Node.js.

Multi-tenancy

O tenant vem da identidade, não do body ou query. Toda chamada ao repository recebe o tenant explicitamente.

Veja Multi-Tenancy no Node.js.

Validação

Hono permite integrar validators e bibliotecas como Zod. Um exemplo conceitual:

const CreateProjectSchema = z.object({
  name: z.string().min(1).max(100),
  description: z.string().max(1000).optional()
}).strict();

app.post('/projects', async c => {
  const input = CreateProjectSchema.parse(
    await c.req.json()
  );

  return c.json(await projectService.create(input), 201);
});

O próximo artigo desta rodada aprofunda Zod.

Validator middleware

Adapters de validação podem colocar o resultado validado no request. Rejeite campos desconhecidos quando o contrato não permite extensões.

Body limit

Use middleware de limite e configure também o proxy. JSON, formulário e multipart precisam de limites diferentes.

Consulte Multipart Upload no Node.js.

CORS

app.use('/api/*', cors({
  origin: ['https://app.example.com'],
  allowMethods: ['GET', 'POST', 'PATCH', 'DELETE'],
  credentials: true
}));

Confirme a API da versão e use allowlist. Consulte CORS em APIs Node.js.

CSRF

Quando usar cookies, habilite proteção CSRF e SameSite adequado. O middleware de CSRF deve considerar origins e métodos.

Secure Headers

Hono oferece middleware para headers. Configure de acordo com API ou aplicação HTML. Para CSP, consulte Helmet e CSP no Node.js.

Cookies

Use helpers para ler e definir cookies, mantendo:

  • HttpOnly;
  • Secure;
  • SameSite;
  • Path restrito;
  • expiração no servidor.

RPC mode

Hono Client pode inferir tipos das rotas quando handlers e schemas são definidos de forma compatível.

export type AppType = typeof app;

O cliente usa esse tipo para chamadas. Assim como no tRPC, a validação runtime continua obrigatória.

Contrato público

Para clientes externos, considere OpenAPI. Consulte OpenAPI com Node.js.

Respostas

return c.json({
  id: project.id,
  name: project.name
}, 201);

Retorne DTOs e não entidades completas.

Erros

app.onError((error, c) => {
  logger.error({
    err: error,
    requestId: c.get('requestId')
  }, 'Falha na API');

  return c.json({
    code: 'INTERNAL_ERROR',
    message: 'Erro interno',
    requestId: c.get('requestId')
  }, 500);
});

Não exponha stack ou detalhes internos.

HTTPException

Use exceções controladas para status específicos, mas mantenha códigos de domínio estáveis.

Not found

app.notFound(c => c.json({
  code: 'NOT_FOUND',
  message: 'Rota não encontrada'
}, 404));

Streaming

Como Hono usa Web Streams, handlers podem devolver conteúdo progressivo. Controle desconexão e backpressure.

Consulte Web Streams API no Node.js.

SSE

Server-Sent Events pode ser usado para atualizações unidirecionais. Envie heartbeat, IDs e trate reconexão.

WebSocket

O adapter e runtime determinam suporte. Consulte WebSocket no Node.js.

Proxy

Hono pode atuar como proxy, mas não construa destino diretamente de input. Aplique as defesas de SSRF no Node.js.

Cache middleware

Cacheie apenas respostas apropriadas. Dados autenticados exigem private ou no-store.

ETag

O middleware ETag ajuda em respostas condicionais. Consulte ETag e Cache HTTP no Node.js.

Compressão

Evite compressão duplicada no framework e proxy. Consulte Compressão HTTP no Node.js.

Timeout middleware

Defina prazo por rota e propague AbortSignal para downstreams. Um timeout de resposta não cancela automaticamente banco ou fetch.

Rate limiting

Use middleware externo ou implementação distribuída. Consulte Rate Limiting no Node.js.

Node.js versus edge

No Node.js, você pode usar filesystem, net e módulos nativos. No edge, APIs e limites são diferentes. Mantenha adapters de infraestrutura separados.

Ports e adapters

Defina interfaces para banco, filas e storage. O handler usa um service independente do runtime.

Variáveis de ambiente

Edge e Node.js fornecem configurações de formas diferentes. Crie uma camada de config tipada e validada.

Banco de dados

Em serverless, cuidado com pools e quantidade de conexões. Em Node.js persistente, use pool dimensionado.

Transações

Delegue a uma camada de serviço. Consulte Transações PostgreSQL no Node.js.

Logging

O logger integrado é útil em desenvolvimento. Em produção, use logs JSON com redaction.

Consulte Logs com Pino no Node.js.

Métricas

Monitore rota normalizada, status, duração, tamanho, erro, event loop e downstreams.

Tracing

Propague traceparent e crie spans para banco e fetch. Consulte OpenTelemetry no Node.js.

Health checks

Crie endpoints leves para liveness e readiness. Não use uma consulta cara em toda probe.

Graceful shutdown

O adapter Node.js retorna ou expõe o servidor HTTP conforme a integração. Capture SIGTERM, pare novas conexões e feche recursos.

Consulte Graceful Shutdown no Node.js.

Testando com app.request()

const response = await app.request('/projects', {
  headers: {
    authorization: `Bearer ${token}`
  }
});

assert.equal(response.status, 200);

Esse método testa o app sem abrir porta.

Teste de context

Confirme que request IDs e identidades ficam isolados entre chamadas concorrentes.

Teste de validação

Envie JSON inválido, campos extras, strings grandes e tipos incorretos.

Teste de autorização

Inclua sem token, permission ausente, outro tenant e recurso fora do escopo.

Teste multi-runtime

Se portabilidade é um requisito, execute uma suíte mínima em cada adapter alvo.

Teste de streaming

Cancele o cliente e confirme interrupção de trabalho e liberação de recursos.

Teste de proxy

Envie URLs privadas e redirects para localhost quando houver funcionalidade externa.

Deploy em Node.js

Compile no CI, execute como usuário não root e configure timeouts do proxy.

Deploy edge

Respeite limites de CPU, memória, tamanho do bundle e conexões do provedor.

Erros comuns

  • Assumir portabilidade automática: dependências usam Node.js.
  • Confiar nos tipos: input da rede não é validado.
  • Context global: identidade vaza.
  • Sem body limit: requisições consomem memória.
  • Middleware de auth sem recurso: autorização fica incompleta.
  • Proxy com URL livre: SSRF aparece.
  • Logs com headers: tokens vazam.

Boas práticas

  • Valide entradas em runtime.
  • Use context tipado.
  • Separe handlers e serviços.
  • Autorize por recurso.
  • Configure limits e timeouts.
  • Use Web Standards quando possível.
  • Isole adapters de runtime.
  • Redija logs.
  • Teste adapters.
  • Implemente shutdown.

Conclusão

Usar Hono no Node.js oferece uma API enxuta, baseada em padrões da Web e preparada para vários runtimes. Rotas, middleware e context permanecem simples e tipados.

A portabilidade depende de separar domínio e infraestrutura, enquanto a segurança exige validação, limites e autorização. Com adapters bem definidos e testes multi-runtime, Hono permite compartilhar a mesma base sem assumir que Node.js, edge e serverless possuem as mesmas capacidades.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita