Hono 4.13.10 split adapters: update a Sume webhook receiver
Hono 4.13.10 moved adapters to @hono/bun, @hono/deno and @hono/cloudflare-workers. The Sume verifyWebhook call needs no change; only the entrypoint imports do.

If you run a Sume webhook receiver on Hono, the 4.13.10 adapter split changes your imports and nothing in the verification code. The Hono release notes dated 2026-09-28 say the adapters now ship as separate packages, and that hono/<adapter> imports are deprecated and removed in v5. The Sume verifyWebhook helper uses WebCrypto, so the same handler runs on Bun, Deno and Workers.
What the Hono releases say
Version 4.13.10 (2026-09-28) lists the new packages. hono/cloudflare-pages is deprecated with no replacement package. Versions 4.13.11 and 4.13.12 followed on 2026-09-29 and 2026-09-30, and 4.13.13 landed on 2026-10-04.
| Runtime or host | New package | Old import |
|---|---|---|
| Bun | @hono/bun | hono/bun (deprecated, removed in v5) |
| Deno | @hono/deno (also on JSR) | hono/deno |
| Cloudflare Workers | @hono/cloudflare-workers | hono/cloudflare-workers |
| AWS Lambda | @hono/aws-lambda | hono/aws-lambda |
| Vercel | @hono/vercel | hono/vercel |
| Cloudflare Pages | None | hono/cloudflare-pages (deprecated) |
Why verification does not change
Sume signs <timestamp>.<raw_body> with HMAC-SHA256. The SDK check is async, returns false for a malformed delivery, and never throws. It reads headers from a Headers object, which is what c.req.raw.headers is in Hono.
Read the body once with c.req.text(). If a middleware parses JSON first, the signed bytes are gone.
The handler
This route is the same on every runtime. Only the line that exports or serves the app differs, and that is where the new adapter package comes in.
import { Hono } from "hono";
import { verifyWebhook } from "@sume-com/sdk";
const app = new Hono<{ Bindings: { SUME_COM_WEBHOOK_SIGNING_SECRET?: string } }>();
app.post("/hooks/sume", async (c) => {
const secret = c.env?.SUME_COM_WEBHOOK_SIGNING_SECRET ?? globalThis.process?.env?.SUME_COM_WEBHOOK_SIGNING_SECRET;
if (!secret) return c.text("not configured", 500);
const body = await c.req.text();
const ok = await verifyWebhook({ body, headers: c.req.raw.headers, secret });
if (!ok) return c.text("bad signature", 401);
const event = JSON.parse(body);
console.log(event.event, event.job_id);
return c.body(null, 204);
});
export default app;Migration steps
Do the swap in one commit and send a webhook.test to confirm.
- Install the package for your runtime and change the import.
- Pin Hono to 4.13.13 or later; 4.13.11 fixed a
serveStaticdouble-decode security issue. - Call
POST /v1/webhooks/test-deliveriesand check for a 204. - Dedupe on
job_id; Sume retries up to 10 times.
Entrypoints by runtime
The route code is the same, so the work is in the file that exports the app. On Workers the app is the default export and the platform calls its fetch. On Bun the default export also works with the runtime server. For Deno, Deno.serve(app.fetch) needs no adapter at all. The adapter packages matter when you use their extras, such as static file serving, which is where the 4.13.11 security fix applied.
If you only receive webhooks, you may not need any adapter package, and removing the import is the simplest way to be ready for v5.
Workers read secrets from the environment binding, Bun and Deno from the process environment. The handler above reads both and refuses an empty value. Do not hard-code the secret and do not log it. The dashboard shows a fingerprint of the secret that is safe to compare with the x-sume-webhook-secret-fingerprint header on each delivery.
Sources
Related posts
More in Developers
- Hono 4.13.13 deprecates app.mount(): mount a Sume webhook sub-app
Hono 4.13.13 deprecates app.mount() in favor of Mount Middleware. A Sume webhook receiver written as a Hono sub-app uses app.route() and keeps its raw body.
- Why input_references fails on Imagen, Recraft, Soul and Qwen Max
Five Sume image rows list zero input_references: imagen-4 fast and ultra, recraft-v4, Soul and qwen-image-max. Check the catalog in Python first.
- Is Higgsfield Genjutsu in your Sume catalog? Check, then price it
higgsfield-genjutsu appears in the catalog only when its provider is configured. List your models, then price a 4 to 30 second source at 480p or 720p.
- Jupyter: move Sora cells to Sume, where a cell rerun is a retry
Re-running a notebook cell resubmits the request. Hold one Idempotency-Key per take in a variable so Sume returns the first video job, and show the file inline.
Written by Sume