Skip to main content
hono Use when building Hono web applications or when the user asks about Hono APIs, routing, middleware, JSX, validation, testing, or streaming. TRIGGER when code imports from 'hono' or 'hono/*', or user mentions Hono. Use `npx hono request` to test endpoints.
Ir para a instalação Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/arvindrk/twitter-agent --skill honoO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando...
Ocupações relacionadas
SOC
Baseado na classificação ocupacional SOC
name hono description Use when building Hono web applications or when the user asks about Hono APIs, routing, middleware, JSX, validation, testing, or streaming. TRIGGER when code imports from 'hono' or 'hono/*', or user mentions Hono. Use `npx hono request` to test endpoints.
Hono Skill
Build Hono web applications. This skill provides inline API knowledge for AI. Use npx hono request to test endpoints. If the hono-docs MCP server is configured, prefer its tools for the latest documentation over the inline reference.
Hono CLI Usage
Request Testing
Test endpoints without starting an HTTP server. Uses app.request() internally.
npx hono request [file] -P /path
npx hono request [file] -X POST -P /api/users -d '{"name": "test"}'
Note: Do not pass credentials directly in CLI arguments. Use environment variables for sensitive values. hono request does not support Cloudflare Workers bindings (KV, D1, R2, etc.). When bindings are required, use workers-fetch instead:
npx workers-fetch /path
npx workers-fetch -X POST -H "Content-Type:application/json" -d '{"name":"test"}' /api/users
Hono API Reference
App Constructor
import { Hono } from "hono" ;
const app = new Hono ();
= {
: { : D1Database; : };
: { : };
};
app = < >();
type
Env
Bindings
DATABASE
KV
KVNamespace
Variables
user
User
const
new
Hono
Env
Routing Methods app.get ("/path" , handler);
app.post ("/path" , handler);
app.put ("/path" , handler);
app.delete ("/path" , handler);
app.patch ("/path" , handler);
app.options ("/path" , handler);
app.all ("/path" , handler);
app.on ("PURGE" , "/path" , handler);
app.on (["PUT" , "DELETE" ], "/path" , handler);
Routing Patterns
app.get ("/user/:name" , (c ) => {
const name = c.req .param ("name" );
return c.json ({ name });
});
app.get ("/posts/:id/comments/:commentId" , (c ) => {
const { id, commentId } = c.req .param ();
});
app.get ("/api/animal/:type?" , (c ) => c.text ("Animal!" ));
app.get ("/wild/*/card" , (c ) => c.text ("Wildcard" ));
app.get ("/post/:date{[0-9]+}/:title{[a-z]+}" , (c ) => {
const { date, title } = c.req .param ();
});
app.get ("/endpoint" , (c ) => c.text ("GET" ))
.post ((c ) => c.text ("POST" ))
.delete ((c ) => c.text ("DELETE" ));
Route Grouping
const api = new Hono ();
api.get ("/users" , (c ) => c.json ([]));
const app = new Hono ();
app.route ("/api" , api);
const app = new Hono ().basePath ("/api" );
app.get ("/users" , (c ) => c.json ([]));
Error Handling app.notFound ((c ) => c.json ({ message : "Not Found" }, 404 ));
app.onError ((err, c ) => {
console .error (err);
return c.json ({ message : "Internal Server Error" }, 500 );
});
Context (c)
Response Methods c.text ("Hello" );
c.json ({ message : "Hello" });
c.html ("<h1>Hello</h1>" );
c.redirect ("/new-path" );
c.redirect ("/new-path" , 301 );
c.body ("raw body" , 200 , headers);
c.notFound ();
Headers & Status c.status (201 );
c.header ("X-Custom" , "value" );
c.header ("Cache-Control" , "no-store" );
Variables (request-scoped data)
c.set ("user" , { id : 1 , name : "Alice" });
const user = c.get ("user" );
const user = c.var .user ;
Environment (Cloudflare Workers) const value = await c.env .KV .get ("key" );
const db = c.env .DATABASE ;
c.executionCtx .waitUntil (promise);
Renderer app.use (async (c, next) => {
c.setRenderer ((content ) =>
c.html (
<html > <body > {content}</body > </html >
)
)
await next ()
})
app.get ('/' , (c ) => c.render (<h1 > Hello</h1 > ))
HonoRequest (c.req) c.req .param ("id" );
c.req .param ();
c.req .query ("page" );
c.req .query ();
c.req .queries ("tags" );
c.req .header ("Authorization" );
c.req .header ();
await c.req .json ();
await c.req .text ();
await c.req .formData ();
await c.req .parseBody ();
await c.req .arrayBuffer ();
await c.req .blob ();
c.req .valid ("json" );
c.req .valid ("query" );
c.req .valid ("form" );
c.req .valid ("param" );
c.req .url ;
c.req .path ;
c.req .method ;
c.req .raw ;
Middleware
Using Built-in Middleware import { cors } from "hono/cors" ;
import { logger } from "hono/logger" ;
import { basicAuth } from "hono/basic-auth" ;
import { prettyJSON } from "hono/pretty-json" ;
import { secureHeaders } from "hono/secure-headers" ;
import { etag } from "hono/etag" ;
import { compress } from "hono/compress" ;
import { poweredBy } from "hono/powered-by" ;
import { timing } from "hono/timing" ;
import { cache } from "hono/cache" ;
import { bearerAuth } from "hono/bearer-auth" ;
import { jwt } from "hono/jwt" ;
import { csrf } from "hono/csrf" ;
import { ipRestriction } from "hono/ip-restriction" ;
import { bodyLimit } from "hono/body-limit" ;
import { requestId } from "hono/request-id" ;
import { methodOverride } from "hono/method-override" ;
import { trailingSlash, trimTrailingSlash } from "hono/trailing-slash" ;
app.use (logger ());
app.use ("/api/*" , cors ());
app.post ("/api/*" , basicAuth ({ username : "admin" , password : "secret" }));
Custom Middleware
app.use (async (c, next) => {
const start = Date .now ();
await next ();
const elapsed = Date .now () - start;
c.res .headers .set ("X-Response-Time" , `${elapsed} ms` );
});
import { createMiddleware } from "hono/factory" ;
const auth = createMiddleware (async (c, next) => {
const token = c.req .header ("Authorization" );
if (!token) return c.json ({ error : "Unauthorized" }, 401 );
await next ();
});
app.use ("/api/*" , auth);
Middleware Execution Order Middleware executes in registration order. await next() calls the next middleware/handler, and code after next() runs on the way back:
Request → mw1 before → mw2 before → handler → mw2 after → mw1 after → Response
app.use (async (c, next) => {
await next ();
});
Validation Validation targets: json, form, query, header, param, cookie.
Zod Validator import { zValidator } from "@hono/zod-validator" ;
import { z } from "zod" ;
const schema = z.object ({
title : z.string ().min (1 ),
body : z.string (),
});
app.post ("/posts" , zValidator ("json" , schema), (c ) => {
const data = c.req .valid ("json" );
return c.json (data, 201 );
});
Valibot / Standard Schema Validator import { sValidator } from "@hono/standard-validator" ;
import * as v from "valibot" ;
const schema = v.object ({ name : v.string (), age : v.number () });
app.post ("/users" , sValidator ("json" , schema), (c ) => {
const data = c.req .valid ("json" );
return c.json (data, 201 );
});
JSX
Setup {
"compilerOptions" : {
"jsx" : "react-jsx" ,
"jsxImportSource" : "hono/jsx"
}
}
Or use pragma: /** @jsxImportSource hono/jsx */
Important: Files using JSX must have a .tsx extension. Rename .ts to .tsx or the compiler will fail.
Components import type { PropsWithChildren } from "hono/jsx" ;
const Layout = (props : PropsWithChildren ) => (
<html >
<head >
<title > My App</title >
</head >
<body > {props.children}</body >
</html >
);
const UserCard = ({ name }: { name: string } ) => (
<div class ="card" >
<h2 > {name}</h2 >
</div >
);
app.get ("/" , (c ) => {
return c.html (
<Layout >
<UserCard name ="Alice" />
</Layout > ,
);
});
jsxRenderer Middleware Use jsxRenderer middleware for layouts. See npx hono docs /docs/middleware/builtin/jsx-renderer for details.
Async Components const UserList = async ( ) => {
const users = await fetchUsers ();
return (
<ul >
{users.map((u) => (
<li > {u.name}</li >
))}
</ul >
);
};
Fragments const Items = ( ) => (
<>
<li > Item 1</li >
<li > Item 2</li >
</>
);
Streaming import { stream, streamText, streamSSE } from "hono/streaming" ;
app.get ("/stream" , (c ) => {
return stream (c, async (stream) => {
stream.onAbort (() => console .log ("Aborted" ));
await stream.write (new Uint8Array ([0x48 , 0x65 ]));
await stream.pipe (readableStream);
});
});
app.get ("/stream-text" , (c ) => {
return streamText (c, async (stream) => {
await stream.writeln ("Hello" );
await stream.sleep (1000 );
await stream.write ("World" );
});
});
app.get ("/sse" , (c ) => {
return streamSSE (c, async (stream) => {
let id = 0 ;
while (true ) {
await stream.writeSSE ({
data : JSON .stringify ({ time : new Date ().toISOString () }),
event : "time-update" ,
id : String (id++),
});
await stream.sleep (1000 );
}
});
});
Testing with app.request() Test endpoints without starting an HTTP server:
const res = await app.request ("/posts" );
expect (res.status ).toBe (200 );
expect (await res.json ()).toEqual ({ posts : [] });
const res = await app.request ("/posts" , {
method : "POST" ,
body : JSON .stringify ({ title : "Hello" }),
headers : { "Content-Type" : "application/json" },
});
const formData = new FormData ();
formData.append ("name" , "Alice" );
const res = await app.request ("/users" , { method : "POST" , body : formData });
const res = await app.request (
"/api/data" ,
{},
{ KV : mockKV, DATABASE : mockDB },
);
const req = new Request ("http://localhost/api" , { method : "DELETE" });
const res = await app.request (req);
Hono Client (RPC) Type-safe API client using shared types between server and client.
IMPORTANT: Routes MUST be chained for type inference to work. Without chaining, the client cannot infer route types.
const route = app
.post ("/posts" , zValidator ("json" , schema), (c ) => {
return c.json ({ ok : true }, 201 );
})
.get ("/posts" , (c ) => {
return c.json ({ posts : [] });
});
export type AppType = typeof route;
import { hc } from "hono/client" ;
import type { AppType } from "./server" ;
const client = hc<AppType >("http://localhost:8787/" );
const res = await client.posts .$post({ json : { title : "Hello" } });
const data = await res.json ();
import type { InferRequestType , InferResponseType } from "hono/client" ;
type ReqType = InferRequestType <typeof client.posts .$post >;
type ResType = InferResponseType <typeof client.posts .$post , 200 >;
Helpers Helpers are utility functions imported from hono/<helper-name>:
import { getConnInfo } from "hono/conninfo" ;
import { getCookie, setCookie, deleteCookie } from "hono/cookie" ;
import { css, Style } from "hono/css" ;
import { createFactory } from "hono/factory" ;
import { html, raw } from "hono/html" ;
import { stream, streamText, streamSSE } from "hono/streaming" ;
import { testClient } from "hono/testing" ;
import { upgradeWebSocket } from "hono/cloudflare-workers" ;
Available helpers: Accepts, Adapter, ConnInfo, Cookie, css, Dev, Factory, html, JWT, Proxy, Route, SSG, Streaming, Testing, WebSocket.
For details, use npx hono docs /docs/helpers/<helper-name>.
Factory Use createFactory to define Env once and share it across app, middleware, and handlers:
import { createFactory } from "hono/factory" ;
const factory = createFactory<Env >();
const app = factory.createApp ();
const mw = factory.createMiddleware (async (c, next) => {
await next ();
});
const handlers = factory.createHandlers (logger (), (c ) =>
c.json ({ message : "Hello" }),
);
app.get ("/api" , ...handlers);
Best Practices
Write handlers inline in route definitions for proper type inference of path params.
Use app.route() to organize large apps by feature, not Rails-style controllers.
Use createFactory() to share Env type across app, middleware, and handlers.
Use c.set()/c.get() to pass data between middleware and handlers.
Chain validators for multiple request parts (param + query + json).
Export app type for RPC: export type AppType = typeof routes
Use app.request() for testing — no server startup needed.
Adapters Hono runs on multiple runtimes. The default export works for Cloudflare Workers, Deno, and Bun. For Node.js, use the Node adapter:
export default app;
import { serve } from "@hono/node-server" ;
serve (app);