@glandjs/hono@1.1.0-beta
@glandjs/hono
The Hono 4 transport, on Node and on the edge.
# pnpm pnpm add @glandjs/hono# npm npm install @glandjs/hono# yarn yarn add @glandjs/hono# bun bun add @glandjs/hono| Package | @glandjs/hono |
| Version | 1.1.0-beta |
| Repository | glandjs/http |
| License | MIT |
| Node | >= 20 |
| Dependencies | @glandjs/core ^1.0.3-beta · @glandjs/events ^1.1.0 · @medishn/toolkit ^1.0.4 · hono ^4.6.14 · tslib ^2.8.1 |
| Peer dependencies | @glandjs/common ^1.0.3-beta · @hono/node-server ^1.13.7 · reflect-metadata ^0.2.2 |
Description
Section titled “Description”@glandjs/hono is the Hono adapter for Gland’s HTTP layer. Because Hono is built
on the Fetch API, this is the only adapter that also runs on Cloudflare Workers,
Deno Deploy, Bun and Lambda — where there is no socket to bind and the
application exports fetch instead.
The same controller, the same middleware and the same reply semantics run on all of them.
Install
Section titled “Install”npm install @glandjs/core @glandjs/common @glandjs/http @glandjs/hono reflect-metadata
Optional, for `listen()` on Node: `@hono/node-server`.
## Usage
On Node:
```tsimport { GlandFactory } from '@glandjs/core';import { HonoBroker, type HonoRequestContext } from '@glandjs/hono';import { Get } from '@glandjs/http';import { Controller, Module } from '@glandjs/common';
@Controller('/products')class ProductController { @Get('/:id') async find(ctx: HonoRequestContext) { return ctx.call('db:product:find', ctx.params.id); }}
@Module({ controllers: [ProductController] })class AppModule {}
const { app, shutdown } = await GlandFactory.create(AppModule);const http = app.connectTo(HonoBroker);
http.listen(3000);await http.ready();On an edge runtime, export the Hono instance:
export default http.hono; // Cloudflare Workers, Deno, BunA fetch Response is immutable
Section titled “A fetch Response is immutable”This is the trade for running everywhere, and it has three consequences.
c.res is replaced, not mutated. A useRaw middleware that sets a header is
merged into the adapter’s reply rather than overwriting it, so
c.header('x-request-id', …) still reaches the client. What it cannot do is
change the status or the body: a fetch Response is immutable, and the adapter’s
is the one the handler’s return value describes. A raw middleware can observe,
add headers, and short-circuit by returning its own Response.
No raw body. A fetch body is read as text, and re-buffering it would mean
holding the whole body twice. The adapter warns at boot and ctx.rawText carries
what was read. For a file upload, use await ctx.req.parseBody() in the handler.
listen() is Node-only. On an edge runtime there is nothing to bind, and the
adapter says so rather than failing.
The body is read once
Section titled “The body is read once”A fetch Request body is a one-shot stream, so the adapter reads it in a
middleware and hands the parsed value to ctx.body. Without that, ctx.body
would be undefined everywhere — and a second read would hang rather than return
nothing.
app.useRaw(async (c, next) => { c.header('x-request-id', crypto.randomUUID()); await next();});| Export | Kind |
|---|---|
HonoBroker / HonoBrokerClass |
What app.connectTo() takes |
HonoCore |
The application, with a typed hono getter |
HonoAdapter |
The adapter |
HonoRequestContext, FetchBodyInit, parseFetchBody |
The context |
The full surface is in the API reference.
Documentation
Section titled “Documentation”License
Section titled “License”MIT