new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Hono · all subjects

api

85 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Hono API overview and structure

Hono's API is simple and composed by extended objects from Web Standards. The main API components are: Hono object, routing, Context object, and middleware.

Export endpoint type for RPC

To enable RPC, export the endpoint type using export type AppType = typeof route. For RPC to correctly infer routes, all methods must be chained and the endpoint or app type must be inferred from a declared variable. See the Best Practices for RPC guide for more details.

Zod validator middleware usage with query parameters

Use zValidator with the 'query' target to validate query parameters. Pass a Zod schema object defining the expected parameters. Then access validated values with c.req.valid('query'). Example: zValidator('query', z.object({ name: z.string() })), then const { name } = c.req.valid('query').

HTTP client creation with hc

Create a type-safe HTTP client by passing an AppType generic to hc: const client = hc<AppType>('/api'). This enables auto-completion and type-safe access to endpoints. Call endpoints using the format client.path.$method() where method is get, post, etc., and specify parameters as needed (e.g., query, form).

Hono Stack components for RPC

The Hono Stack consists of four components: Hono (API Server), Zod (Validator), Zod Validator Middleware (@hono/zod-validator), and hc (HTTP Client). These components work together to enable type-safe RPC communication where the client generated by hc reads the API spec and accesses endpoints with type safety.

Zod validator middleware usage with form data

Use zValidator with the 'form' target to validate form data submitted to an endpoint. Pass a Zod schema object defining the expected form fields. Then access validated values with c.req.valid('form'). Example: zValidator('form', z.object({ id: z.string(), title: z.string() })), then const formData = c.req.valid('form').

InferResponseType and InferRequestType utilities

Use InferResponseType<typeof endpoint> to infer the response type of an endpoint, and InferRequestType<typeof endpoint> to infer the request type. These utilities are exported from 'hono/client' and enable type-safe usage of client endpoints with React Query and other frameworks.

Client response handling with type inference

The Response object returned by client method calls is compatible with the fetch API. Call res.json() to retrieve the data, which will be typed according to the server-side endpoint definition. Use InferResponseType and InferRequestType utilities from 'hono/client' for advanced type inference in client code.

Hono uses Web Standards like Fetch

Hono uses only Web Standards such as Fetch, which consist of basic objects that handle HTTP requests and responses including Request, Response, URL, URLSearchParam, Headers and others.

Binary data response on AWS Lambda

Hono supports binary data responses on AWS Lambda. When binary type is set in the Content-Type header, Hono automatically encodes the data to base64. Use `c.body(buffer)` to return binary data; buffer must be of ArrayBufferLike type.

Accessing AWS Lambda request context

To access AWS Lambda request context in Hono, import LambdaEvent type from 'hono/aws-lambda', define a Bindings type with event property, bind it to Hono, and access via `c.env.event.requestContext`.

AWS Lambda runtime requirements

Hono works on AWS Lambda with the Node.js 18+ environment.

AWS Lambda setup with yarn

To set up a Hono project on AWS Lambda with yarn: run `mkdir my-app && cd my-app && cdk init app -l typescript && yarn add hono && yarn add -D esbuild && mkdir lambda && touch lambda/index.ts`.

AWS Lambda setup with pnpm

To set up a Hono project on AWS Lambda with pnpm: run `mkdir my-app && cd my-app && cdk init app -l typescript && pnpm add hono && pnpm add -D esbuild && mkdir lambda && touch lambda/index.ts`.

AWS Lambda setup with bun

To set up a Hono project on AWS Lambda with bun: run `mkdir my-app && cd my-app && cdk init app -l typescript && bun add hono && bun add -D esbuild && mkdir lambda && touch lambda/index.ts`.

Hello World on AWS Lambda

Basic Hono application on AWS Lambda using handle adaptor: `import { Hono } from 'hono'; import { handle } from 'hono/aws-lambda'; const app = new Hono(); app.get('/', (c) => c.text('Hello Hono!')); export const handler = handle(app)`.

AWS Lambda request context (deprecated before v3.10.0)

Before Hono v3.10.0, AWS Lambda request context was accessed by importing ApiGatewayRequestContext type from 'hono/aws-lambda', defining a Bindings type with requestContext property, and accessing via `c.env.requestContext`. This approach is deprecated as of v3.10.0.

AWS Lambda response streaming setup

To enable response streaming on AWS Lambda, add `invokeMode: lambda.InvokeMode.RESPONSE_STREAM` to the addFunctionUrl configuration and use `streamHandle` instead of `handle` from 'hono/aws-lambda'.

AWS Lambda streaming handler example

Example of streaming response on AWS Lambda: `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);`.

AWS Lambda CDK stack configuration

AWS Lambda CDK stack must create a NodejsFunction with entry pointing to lambda handler file, handler name 'handler', and runtime set to lambda.Runtime.NODEJS_22_X. Add a function URL with authType set to lambda.FunctionUrlAuthType.NONE.

Deploying Hono to AWS Lambda

Deploy a Hono application on AWS Lambda by running `cdk deploy` command.

Return JSON response

To return JSON, use the `c.json()` method: `app.get('/api/hello', (c) => c.json({ ok: true, message: 'Hello Hono!' }))`

WebSocket support on Cloudflare Workers

To handle WebSocket on Cloudflare Workers, import `upgradeWebSocket` from `hono/cloudflare-workers` and use it: `app.get('/ws', upgradeWebSocket((c) => { ... }))`

Return text response

Use `c.text('message')` to return a plain text response. You can optionally pass a status code as the second argument, e.g., `c.text('Created!', 201)`.

Return HTML with JSX

To return HTML using JSX, rename the file to `.tsx`, write JSX components, and use `c.html(<Component />)` to return the HTML response. For example: `const View = () => (<html><body><h1>Hello Hono!</h1></body></html>)` and `app.get('/page', (c) => c.html(<View />))`

Return raw Response

You can return a raw Response object directly: `app.get('/', () => new Response('Good morning!'))`

Basic authentication middleware

Import `basicAuth` from `hono/basic-auth` and use it with `app.use('/admin/*', basicAuth({ username: 'admin', password: 'secret' }))`to protect routes with HTTP Basic Authentication.

Built-in middleware types

Hono provides built-in middleware for Basic Authentication, Bearer authentication, JWT authentication, CORS, and ETag. Third-party middleware is also available for GraphQL Server and Firebase Auth.

serveStatic options for Bun

The serveStatic middleware for Bun (from 'hono/bun') accepts the following options: root (string, directory root path), path (string, file path), rewriteRequestPath (function to rewrite request paths), mimes (object with MIME type mappings), onFound (callback when file is found), onNotFound (callback when file is not found), and precompressed (boolean to serve pre-compressed files based on Accept-Encoding).

serveStatic root option

The root option in serveStatic specifies the directory from which to serve static files. Example: `serveStatic({ root: './' })` serves from the current directory.

serveStatic mimes option

Add custom MIME types to serveStatic with the mimes option, which accepts an object mapping file extensions to MIME type strings. Example: `mimes: { m3u8: 'application/vnd.apple.mpegurl', ts: 'video/mp2t' }`.

serveStatic onFound callback

The onFound option accepts a callback function that runs when a requested file is found. The callback receives the file path and context object. Example: set cache headers with `onFound: (_path, c) => { c.header('Cache-Control', 'public, immutable, max-age=31536000') }`.

serveStatic onNotFound callback

The onNotFound option accepts a callback function that runs when a requested file is not found. The callback receives the requested path and context object. Example: `onNotFound: (path, c) => { console.log(`${path} is not found, you access ${c.req.path}`) }`.

serveStatic precompressed option

When precompressed is set to true, serveStatic checks for pre-compressed versions of files with extensions like .br (Brotli), .zst (Zstd), or .gz (Gzip) and serves them based on the Accept-Encoding header. Priority order is Brotli, then Zstd, then Gzip. If no compressed version is available, the original file is served.

serveStatic middleware for Deno

To serve static files in Hono on Deno, import and use serveStatic from hono/deno. Example: app.use('/static/*', serveStatic({ root: './' })). This middleware serves files from the specified root directory.

serveStatic options: root, path, rewriteRequestPath, mimes, onFound, onNotFound, precompressed

The serveStatic middleware accepts the following options: - root (string): Base directory to serve files from - path (string): Specific file path to serve - rewriteRequestPath (function): Function to rewrite the request path before looking up files - mimes (object): Custom MIME type mappings, e.g., { m3u8: 'application/vnd.apple.mpegurl', ts: 'video/mp2t' } - onFound (function): Callback invoked when a requested file is found, receives path and context - onNotFound (function): Callback invoked when a requested file is not found, receives path and context - precompressed (boolean): When true, checks for precompressed files (.br, .gz) and serves based on Accept-Encoding header, prioritizing Brotli, then Zstd, then Gzip

Hono fastest router on Cloudflare Workers

In Cloudflare Workers benchmarks, Hono achieved 402,820 ops/sec (±4.78% over 80 runs), outperforming itty-router (212,598 ops/sec), sunder (297,036 ops/sec), and worktop (197,345 ops/sec). Benchmark was run on Apple MacBook Pro M1 Pro with 32 GiB RAM.

Hono fastest framework on Deno

In Deno benchmarks, Hono v3.0.0 achieved 136,112 requests/sec, outperforming Fast v4.0.0-beta.1 (103,214 req/sec), Megalo v0.3.0 (64,597 req/sec), Faster v5.7 (54,801 req/sec), oak v10.5.1 (43,326 req/sec), and opine v2.2.0 (30,700 req/sec). Benchmark was run on Deno v1.22.0 on Apple MacBook Pro M1 Pro with 32 GiB RAM using bombardier with 100 concurrent connections for 10 seconds against the route /user/lookup/username/foo.

Hono performance on Bun

Hono is one of the fastest frameworks for Bun according to the SaltyAom/bun-http-framework-benchmark.

Lambda@Edge deployment configuration

When deploying Lambda@Edge with CDK, set the region to 'us-east-1' in the environment configuration. The Lambda function should use NodejsFunction with entry pointing to the lambda/index_edge.ts file and handler named 'handler'. The runtime must be lambda.Runtime.NODEJS_20_X or compatible Node.js version.

Lambda@Edge runtime support

Hono supports Lambda@Edge with Node.js 18+ environment.

Lambda@Edge hello world example

To create a Hono app on Lambda@Edge, import Hono and the handle function from 'hono/lambda-edge', create an app instance, define routes, and export the handler. Example: import { Hono } from 'hono'; import { handle } from 'hono/lambda-edge'; const app = new Hono(); app.get('/', (c) => c.text('Hello Hono on Lambda@Edge!')); export const handler = handle(app);

Lambda@Edge setup with CDK

To set up a Hono Lambda@Edge project, initialize with CDK using 'cdk init app -l typescript', install hono, and create a lambda directory. The entry point should be in lambda/index_edge.ts with the handler exported from 'hono/lambda-edge'.

Lambda@Edge CloudFront integration

Hono Lambda@Edge functions integrate with CloudFront distributions. The Lambda function is attached to a distribution's defaultBehavior using the edgeLambdas array, with the eventType set to cloudfront.LambdaEdgeEventType.VIEWER_REQUEST.

Lambda@Edge callback function

Lambda@Edge provides a callback mechanism via c.env.callback() to continue request processing after middleware verification. The callback accepts two parameters: an error (or null) and a CloudFrontRequest object. To use it, define Bindings with callback of type Callback and request of type CloudFrontRequest.

Lambda@Edge callback example with basic auth

Example of using callback with basic auth verification: import { Hono } from 'hono'; import { basicAuth } from 'hono/basic-auth'; import type { Callback, CloudFrontRequest } from 'hono/lambda-edge'; import { handle } from 'hono/lambda-edge'; type Bindings = { callback: Callback; request: CloudFrontRequest }; const app = new Hono<{ Bindings: Bindings }>(); app.get('*', basicAuth({ username: 'hono', password: 'acoolproject' })); app.get('/', async (c, next) => { await next(); c.env.callback(null, c.env.request); }); export const handler = handle(app);

Service Worker tsconfig.json configuration

When configuring TypeScript for a Hono Service Worker project, the tsconfig.json should have: target set to ES2020, module set to ESNext, lib array containing ES2020, DOM, and WebWorker, and moduleResolution set to bundler.

Service Worker adapter for Hono

Hono can run as a Service Worker using a Service Worker adapter. A Service Worker is a script that runs in the background of the browser to handle tasks like caching and push notifications. The Hono application runs as a FetchEvent handler within the browser.

Service Worker registration with scope and type

Service Workers are registered using navigator.serviceWorker.register() with the worker script path and an options object. The options object can include scope to specify the path the worker handles, and type set to 'module' to support ES modules.

handle() function for Service Worker

The handle() function from 'hono/service-worker' registers a Hono application to the fetch event in a Service Worker. It is used with self.addEventListener('fetch', handle(app)) to allow the Hono application to intercept requests.

fire() function for Service Worker

The fire() function from 'hono/service-worker' automatically calls addEventListener('fetch', handle(app)) for you, providing a more concise way to register a Hono application as a Service Worker without manually setting up the event listener.

Service Worker example with Hono

Example of creating and registering a Hono app in a Service Worker: ```ts declare const self: ServiceWorkerGlobalScope import { Hono } from 'hono' import { handle } from 'hono/service-worker' const app = new Hono().basePath('/sw') app.get('/', (c) => c.text('Hello World')) self.addEventListener('fetch', handle(app)) ``` Alternatively using fire(): ```ts import { Hono } from 'hono' import { fire } from 'hono/service-worker' const app = new Hono().basePath('/sw') app.get('/', (c) => c.text('Hello World')) fire(app) ```

Service Worker registration script example

Example JavaScript code to register and manage a Service Worker: ```ts function register() { navigator.serviceWorker .register('/sw.ts', { scope: '/sw', type: 'module' }) .then( function (_registration) { console.log('Register Service Worker: Success') }, function (_error) { console.log('Register Service Worker: Error') } ) } function start() { navigator.serviceWorker .getRegistrations() .then(function (registrations) { for (const registration of registrations) { console.log('Unregister Service Worker') registration.unregister() } register() }) } start() ```

Helpers vs middleware distinction

Helpers are functions available to assist in developing applications. Unlike middleware, they do not act as handlers but rather provide useful functions.

Cookie helper functions

The Cookie helper provides getCookie and setCookie functions. getCookie(c, name) retrieves a cookie by name from the context. setCookie(c, name, value) sets a cookie with the given name and value. Import with: import { getCookie, setCookie } from 'hono/cookie'

Available helpers in Hono

Hono provides the following built-in helpers: Accepts, Adapter, Cookie, css, Dev, Factory, html, JWT, SSG, Streaming, Testing, and WebSocket.

app.request method for testing

The app.request method is the primary way to test Hono applications. It accepts a path, optional request options object, and optional environment object. Basic syntax: app.request(path, requestOptions, env). This allows you to create Request objects and validate Response objects in tests.

Testing GET requests with app.request

To test a GET request with app.request, pass the path and await the response. Example: const res = await app.request('/posts'); expect(res.status).toBe(200); expect(await res.text()).toBe('Many posts')

Testing POST requests with app.request

To test a POST request with app.request, pass the path and an options object with method property set to 'POST'. Example: const res = await app.request('/posts', { method: 'POST' }); expect(res.status).toBe(201);

Testing POST with JSON data

To send JSON data in a POST request test, pass both the body as JSON.stringify and the Content-Type header. Example: const res = await app.request('/posts', { method: 'POST', body: JSON.stringify({ message: 'hello hono' }), headers: new Headers({ 'Content-Type': 'application/json' }) });

Give your agent this brain