@api-envelope/hono
v0.1.1
Published
Response helper factory for sending standardized API Envelope responses from Hono route handlers.
Maintainers
Readme
@api-envelope/hono
Response helper factory for sending standardized API Envelope responses from Hono route handlers.
Table of contents
- Why use this
- Install
- Quick start
- Configuration — custom codes
- Type-safe custom codes
- Things to know
- API reference
- FAQ
- License
Why use this
Hono runs on everything from Node to Cloudflare Workers to Deno — a
runtime-agnostic response shape matters even more there than in a
single-runtime framework. createHonoEnvelope() gives you one consistent
JSON body and status resolution wherever your Hono app actually runs.
Install
npm install @api-envelope/honoRequires hono in your project (peer dependency). @api-envelope/core
is installed automatically.
Quick start
import { Hono } from "hono";
import { createHonoEnvelope } from "@api-envelope/hono";
const app = new Hono();
const envelope = createHonoEnvelope();
app.get("/users/:id", (c) => {
const user = { id: c.req.param("id"), name: "Ada" };
return envelope.ok(c, { code: "OK", data: user });
});
app.get("/users/:id/missing", (c) => {
return envelope.fail(c, { code: "NOT_FOUND", message: "User does not exist" });
});envelope.ok(c, ...) returns 200 { success: true, code: "OK", status: 200, message: "...", data: {...} }.
envelope.fail(c, ...) returns 404 { success: false, code: "NOT_FOUND", status: 404, message: "User does not exist" }.
Unlike Express/Fastify (which decorate res/reply directly), Hono's
helpers take the request Context (c) as their first argument and
return the Response — call createHonoEnvelope() once per app and
reuse the returned envelope object across your routes.
Configuration — custom codes
const envelope = createHonoEnvelope({
codes: [
{ code: "USER_NOT_FOUND", status: 404 },
{ code: "INVALID_TOKEN", status: 401 },
],
});
app.get("/users/:id", (c) => {
if (!userExists) {
return envelope.fail(c, { code: "USER_NOT_FOUND" });
}
return envelope.ok(c, { code: "OK", data: user });
});Built-in codes (OK, SUCCESS, CREATED, NOT_FOUND, ...) are always
available; see @api-envelope/core
for the full default list. Custom codes can also override a default —
e.g. registering { code: "SUCCESS", status: 201 } for a creation-only
envelope.
Type-safe custom codes
import type { DefaultCode } from "@api-envelope/hono";
type AppCode = DefaultCode | "USER_NOT_FOUND";
app.get("/users/:id", (c) => {
return envelope.fail<AppCode>(c, { code: "USER_NOT_FOUND" }); // autocompleted & checked
});Things to know
- Create the envelope once, outside your route handlers. Calling
createHonoEnvelope()inside a handler creates a fresh, isolated code registry on every request, which throws away any custom codes state unnecessarily and wastes work. - Always pass
c. Unlike Express/Fastify's decorated objects, Hono's helpers need the requestContextexplicitly to build theResponse. - Works across Hono's runtimes. Because the return value is a native
Response, this behaves the same on Node, Bun, Deno, or Cloudflare Workers. - Custom codes can override defaults, the same as every other adapter.
API reference
createHonoEnvelope(options?)
Returns { ok, fail }. options.codes is an optional array of
{ code, status } pairs registered on top of the built-in defaults.
envelope.ok(c, { code, data, message? })
Returns a JSON Response with the matching HTTP status.
envelope.fail(c, { code, message? })
Returns a JSON Response with the matching HTTP status.
Both throw if code hasn't been registered — check for typos in custom
codes, or make sure options.codes was passed to createHonoEnvelope().
FAQ
Why does envelope.ok() need c but Express's res.ok() doesn't?
Express/Fastify mutate a response object that already exists per-request.
Hono handlers instead return a Response, and building one requires
c.json(...), which is why c is passed in.
Can I share one envelope across multiple Hono apps?
Yes, as long as they should share the same custom codes — the registry
lives on the envelope object, not on any particular Hono instance.
Does this work on Cloudflare Workers / Deno / Bun?
Yes — it only depends on the Web-standard Response object, which all of
Hono's supported runtimes provide.
License
MIT © 2026 ltimsina
Copyright (c) [2026] [ltimsina]
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
See also
@api-envelope/core— shared types and the code registry these helpers build on.
