better-push
Integrate your stack

Hono

Mount better-push on Hono - four lines, and nothing is adapted.

Hono speaks web standards, and so does better-push. c.req.raw is already a Request and push.handler already returns a Response, so this integration unwraps a context and stops.

src/server.ts
import { Hono } from "hono";
import { toHonoHandler } from "@better-push/core/hono";
import { push } from "./push";

const app = new Hono();
app.all("/api/push/*", toHonoHandler(push));

export default app;

That is the file this project's conformance suite boots and asserts against - including the Server-Sent Events case, which streams here because the runtime under Hono already streams a Response body.

basePath in the better-push config must match the mount path: the router matches on the full pathname, not on what Hono stripped.

No hono dependency is added to your app by better-push. The context is typed structurally as { req: { raw: Request } }.

Any runtime Hono runs on

Because nothing is adapted, better-push runs wherever Hono does - as long as the rest of your configuration does too:

RuntimeWorksCaveat
Node (@hono/node-server)YesThe reference setup.
Bun, DenoYespg and firebase-admin need Node APIs; check your driver and providers.
Cloudflare Workers, Vercel EdgeNopostgresAdapter needs pg, and apns() needs node:http2.

Edge is a deliberate non-goal rather than an oversight: better-push talks to Postgres and to APNs over HTTP/2, and both want Node.

Mounting under a base path

const api = new Hono();
api.all("/push/*", toHonoHandler(push));

const app = new Hono();
app.route("/api", api);

basePath is still /api/push here - the path the client requests - because that is what the router sees.

On this page