hono-wait-until
v2.1.0
Published
[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [![Codecov][codecov-src]][codecov-href] [![Bundlejs][bundlejs-src]][bundlejs-href] [![jsDocs.io][jsDocs-src]][jsDocs-href]
Readme
hono-wait-until 
hono-wait-until provides a waitUntil helper + middleware that make background/async work survive after the response returns.
It automatically falls through to the platform's native waitUntil (Cloudflare Workers, Deno, Bun, Netlify, Vercel Edge, ...) via c.executionCtx.waitUntil when available — no shim, no blocking.
On runtimes without a native waitUntil (Node, AWS Lambda, ...), it shims one: the middleware collects all wrapped promises and blocks until they settle before returning the response, so the platform won't kill your app with uncompleted async tasks.
Usage
Install package:
# npm
npm install hono-wait-until
# yarn
yarn add hono-wait-until
# pnpm (recommended)
pnpm install hono-wait-untilImport:
import type { WaitUntilList } from 'hono-wait-until'
import {
waitUntil, // Optional helper function instead of accessing via context
waitUntilMiddleware,
} from 'hono-wait-until'
const app = new Hono<{ Variables: { waitUntilList: WaitUntilList } }>()
// Preferably, use the waitUntilMiddleware as early as you can.
.use(waitUntilMiddleware())
.get('/context', async (c) => {
const waitUntilList = c.get('waitUntilList')
waitUntilList.waitUntil(sleep(300))
return c.text(`Using waitUntil via context variable`)
})
.get('/helper', async (c) => {
waitUntil(sleep(300), c)
return c.text(`Using waitUntil via helper function`)
})If any of the wrapped async tasks rejects, the middleware logs the errors and responds with a 500 (Some async tasks were rejected).
Native waitUntil fallthrough
On platforms that expose a native execution-context waitUntil (Cloudflare Workers, Deno, Bun, Netlify, Vercel Edge, ...), both waitUntil() and waitUntilMiddleware() delegate straight to c.executionCtx.waitUntil:
waitUntil()works without the middleware.- The middleware becomes a no-op (it will not block, since the runtime already keeps execution alive and reports errors itself).
On runtimes without native waitUntil (Node, AWS Lambda, ...), the middleware must be applied and will block until every wrapped task settles.
Options
continueWithoutSettled
Pass { continueWithoutSettled: true } to waitUntilMiddleware to respond immediately without blocking until all async tasks settle. This effectively disables the middleware and is useful when you have migrated to a platform that supports background async tasks, but want a test run without removing the waitUntil wrappers:
app.use(waitUntilMiddleware({ continueWithoutSettled: true }))Roadmap
- [ ] Become the legendary 10000x developer
