defer()
Request-scoped deferred work API, inline callbacks and named Runtime targets.
import {
defer,
CruxDeferError,
DEFER_ERROR_CODES,
type DeferredWorkRef,
type DeferredCallback,
} from '@use-crux/core'Overview
defer is a dual overload on the package root. Prefer overloads over casts:
named targets come first; unbranded callbacks select the inline form.
defer(callback)
| Parameter | Type | Description |
|---|---|---|
callback | () => void | PromiseLike<void> | Lazy zero-argument callback |
Returns: void
Registers work on the nearest compatible invocation scope. The callback starts after the host’s declared completion class. Failures are contained and observed; they do not fail an already-committed response.
Throws:
DEFER_SCOPE_REQUIRED: no active scopeDEFER_CAPABILITY_MISSING: scope lacks inline supportDEFER_SCOPE_SEALED/DEFER_LIMIT_EXCEEDED: lifecycle boundsDEFER_REPLAY_UNSAFE: inside replayable flow execution
defer(target, input)
| Parameter | Type | Description |
|---|---|---|
target | branded RuntimeTaskTarget | Exported durableTask(...) (or compatible) target |
input | inferred JSON-safe input | Required for V1 targets constrained to JsonValue |
Returns: Promise<DeferredWorkRef>
interface DeferredWorkRef {
readonly kind: 'deferred.work'
readonly workId: string
readonly targetId: string
}Resolves after durable staging acceptance. Execution still waits for successful
logical finalization and outbox release. Host adapters must await the scope
committed barrier before committing the response.
Throws or poisons commit with:
RUNTIME_REQUIRED(cause) /DEFER_COMMIT_FAILED(host barrier)DEFER_CAPABILITY_MISSINGwhen the host cannot finalize named workDEFER_TARGET_INPUT_REQUIREDfor missing input at runtimeDEFER_REPLAY_UNSAFEinside replayable flows
Host subpaths
| Import | Purpose |
|---|---|
@use-crux/core/defer/node | Node HTTP withNodeDefer / createNodeDeferHost |
@use-crux/core/defer/serverless | withWaitUntilDefer, withAfterDefer, withNamedOnlyDefer, factories |
@use-crux/next | Next.js withNextDefer binding after() |
Internal first-party SPI (not application API):
@use-crux/core/internal/defer-host@use-crux/core/internal/defer-lifecycle
Host lifetime semantics
Completion classes
Each host lifetime declares a completion class describing when inline deferred callbacks may start relative to the response:
response-finished: callbacks start only after the response has fully finished (Node HTTP viawithNodeDefer, Next.js viaafter(), per-process multiprocess Node hosts).handler-returned: callbacks may start as soon as the handler returns, and may overlap a still-streaming response body (waitUntil-based hosts such as Vercel Functions and Cloudflare Workers).- Named-only lifetimes (Lambda
withNamedOnlyDefer, Convex bridge runs) have no inline completion class; inlinedefer(callback)throwsDEFER_CAPABILITY_MISSING.
durableFinalization advertisement
A host lifetime advertises durableFinalization: true only when it can await
the named-defer commit barrier before committing the response. Named
await defer(target, input) requires a configured Runtime plus a lifetime
advertising durable finalization; raw Node hosts advertise
durableFinalization: false unless the wrapper opts in (for example
withNamedOnlyDefer(handler, { durableFinalization: true })).
Capability is explicit, never inferred
Never infer host correctness from environment variable names (VERCEL, etc.).
Capability comes only from the wrapper or platform hook that is explicitly
installed (waitUntil, after, a lifetime port); an installed package or a
recognizable environment alone is not treated as proof of a working lifetime.
Diagnostics
| Code | Docs |
|---|---|
DEFER_SCOPE_REQUIRED | /docs/errors/DEFER_SCOPE_REQUIRED |
DEFER_CAPABILITY_MISSING | /docs/errors/DEFER_CAPABILITY_MISSING |
DEFER_SCOPE_SEALED | /docs/errors/DEFER_SCOPE_SEALED |
DEFER_LIMIT_EXCEEDED | /docs/errors/DEFER_LIMIT_EXCEEDED |
DEFER_REPLAY_UNSAFE | /docs/errors/DEFER_REPLAY_UNSAFE |
DEFER_TARGET_INPUT_REQUIRED | /docs/errors/DEFER_TARGET_INPUT_REQUIRED |
DEFER_COMMIT_FAILED | /docs/errors/DEFER_COMMIT_FAILED |
Observed drain outcomes (not always thrown to the handler):
DEFER_CALLBACK_FAILEDDEFER_TIMED_OUTDEFER_CANCELLED
Related
- Guide: Request-scoped defer
- Guide: Hosts
- Reference: Runtime Engine
- Reference: Flows