Hono Web Framework
repository·main·Indexed 41 days ago
https://github.com/honojs/websiteA small, fast, web standard-based web framework. Hono leverages standard Web APIs like Request, Response, and Fetch, providing a lightweight interface for building applications on runtimes such as Cloudflare Workers, Bun, Deno, and Node.js. Key features include a flexible Context object for request/response handling, built-in support for HTTPExceptions, and a variety of router presets optimized for different deployment environments.
What's inside Hono
- This repository contains the source code and assets for the official Hono website (hono.dev). The site is built using VitePress and is deployed to Cloudflare Workers. Note that the website itself does not use the Hono framework.
Overview of Hono web framework
mainHono is a small, simple, and ultrafast web framework built on Web Standards. It is designed to be lightweight and highly portable across various JavaScript runtimes.
Key Features
- Ultrafast & Lightweight: Uses the
RegExpRouterfor high performance. Thehono/tinypreset is under 14kB. - Multi-runtime Support: The same code runs on Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Netlify, AWS Lambda, Lambda@Edge, and Node.js.
- Batteries Included: Provides built-in middleware, support for custom and third-party middleware, and various helpers.
- Delightful DX: Offers clean APIs and first-class TypeScript support.
- Ultrafast & Lightweight: Uses the
Supported runtimes for Hono
mainHono can run on any runtime that supports Web Standards. Supported environments include:
- Cloudflare Workers (
workerd) - Deno
- Bun
- Fastly Compute
- AWS Lambda
- Node.js (via a Node.js adapter)
- Vercel (edge-light)
- WebAssembly (via [WebAssembly System Interface (WASI)][wasi] and [
wasi:http][wasi-http]) - Netlify and other platforms compatible with Web Standards.
Because of this architecture, the same Hono code can be deployed across all these platforms without changes.
- Cloudflare Workers (
Use the Route Helper for enhanced routing information
mainThe Route Helper provides tools to access detailed information about matched routes and the current route being processed. This is particularly useful for debugging and developing middleware. You can import the following helpers from
hono/route:matchedRoutes(c): Returns an array of all matched routes.routePath(c, [index]): Returns the route path pattern.baseRoutePath(c, [index]): Returns the base path pattern.basePath(c): Returns the base path with embedded parameters from the actual request.
import { Hono } from 'hono' import { matchedRoutes, routePath, baseRoutePath, basePath, } from 'hono/route'Explore Third-party Middleware for Hono
mainHono supports a wide ecosystem of third-party middleware that are not bundled with the core package. These middleware components typically leverage external libraries to provide specialized functionality such as authentication, validation, monitoring, and more. You can find these packages in the official Hono middleware repository or via individual community maintainers.What is a Hono Stack and RPC?
mainA Hono Stack is a combination of components used to build full-stack applications with end-to-end type safety. It typically consists of:
- Hono: The API Server.
- Zod: The validator for request data.
- Zod Validator Middleware:
@hono/zod-validatorto bridge Zod and Hono. hc(HTTP Client): The client that reads the API specification to provide type-safe endpoint access.
This setup enables RPC (Remote Procedure Call), allowing the client to access endpoint types and request shapes automatically based on the server's implementation.
What is middleware in Hono
mainIn Hono, a 'Handler' is the primitive that returns aResponse. 'Middleware' is a function that executes both before and after the Handler, intercepting theRequestandResponse. This follows an 'onion structure' where middleware wraps around the core handler, allowing you to perform actions before the request reaches the handler and after the response is generated.Enable Lambda Response Streaming
mainTo use AWS Lambda's Response Streaming feature, you must set the
invokeModetoRESPONSE_STREAMin your CDK configuration.In your Hono code, instead of using
handle, you must usestreamHandlefromhono/aws-lambdato support traditional Hono streaming (e.g., usingstreamText).// CDK Configuration fn.addFunctionUrl({ authType: lambda.FunctionUrlAuthType.NONE, invokeMode: lambda.InvokeMode.RESPONSE_STREAM, }) // Hono Implementation import { Hono } from 'hono' import { streamHandle } from 'hono/aws-lambda' import { streamText } from 'hono/streaming' const app = new Hono() app.get('/stream', async (c) => { return streamText(c, async (stream) => { for (let i = 0; i < 3; i++) { await stream.writeln(`${i}`) await stream.sleep(1) } }) }) export const handler = streamHandle(app)Import Hono and middleware in Deno (npm vs JSR)
mainHono is available via both
npmandjsr. When using Deno, you must configure yourdeno.jsonimports correctly.Important for Middleware: To use Hono middleware, you must use the Deno directory syntax for the Hono import (e.g.,
hono/mapping tonpm:/hono/).Consistency Rule: For proper TypeScript type inference, ensure that Hono and any third-party middleware you use come from the same registry (either both from
npmor both fromjsr).Example using npm:
{ "imports": { "hono": "npm:hono", "zod": "npm:zod", "@hono/zod-validator": "npm:@hono/zod-validator", "hono/": "npm:/hono/" } }Example using JSR:
{ "imports": { "hono": "jsr:@hono/hono", "zod": "npm:zod", "@hono/zod-validator": "jsr:@hono/zod-validator" } }Use Combine Middleware to group middleware functions
mainCombine Middleware allows you to group multiple middleware functions into a single middleware unit using logical operators. This is useful for implementing complex access control, conditional rate limiting, or environment-specific rules.
To use Combine Middleware, import the desired logic function from
hono/combine:import { some, every, except } from 'hono/combine'import { Hono } from 'hono' import { some, every, except } from 'hono/combine' const app = new Hono() // Example of complex access control app.use( '*', some( every( ipRestriction(getConnInfo, { allowList: ['192.168.0.2'] }), bearerAuth({ token }) ), rateLimit() ) )Implement dynamic CORS logic with callbacks
mainYou can pass callback functions to the
originandallowMethodsoptions to determine allowed values dynamically based on the incoming request's origin or the HonoContext.This is useful for allowing multiple subdomains or restricting specific methods to specific origins.
// Dynamic origin based on subdomain app.use( '/api4/*', cors({ origin: (origin, c) => { return origin.endsWith('.example.com') ? origin : 'http://example.com' }, }) ) // Dynamic methods based on origin app.use( '/api5/*', cors({ origin: (origin) => origin === 'https://example.com' ? origin : '*', allowMethods: (origin, c) => origin === 'https://example.com' ? ['GET', 'HEAD', 'POST', 'PATCH', 'DELETE'] : ['GET', 'HEAD'], }) )Use the Factory Helper to manage TypeScript types
mainThe Factory Helper simplifies creating Hono components like Middleware and Apps while ensuring consistent TypeScript types for
Env(Bindings and Variables). Instead of manually passingEnvtypes to every middleware and application instance, you define them once in a factory.import { createFactory } from 'hono/factory' type Env = { Variables: { foo: string } } const factory = createFactory<Env>() // All components created from this factory inherit the Env type const app = factory.createApp() const middleware = factory.createMiddleware(async (c, next) => { const value = c.var.foo // Properly typed await next() })