CookbookBasics
Node request-scoped defer
Use primitive-local work directly, or add a Node HTTP boundary for response-scoped work.
Inside an agent, adapter, tool, or Safety session, a long-lived Node process needs no host setup:
import { defer } from "@use-crux/core";
const indexCustomer = async (customer: Customer) => {
defer(() => updateSearchIndex(customer));
return customer;
};Root-level request work needs the Node response boundary so Crux knows when the
response finishes. Use createNodeDeferHost when graceful shutdown matters:
import { createServer } from "node:http";
import { defer } from "@use-crux/core";
import { createNodeDeferHost } from "@use-crux/core/defer/node";
const deferHost = createNodeDeferHost();
const server = createServer(
deferHost.wrap(async (_request, response) => {
defer(() => flushAnalytics());
response.statusCode = 200;
response.end("ok");
}),
);
server.listen(3000);
process.once("SIGTERM", async () => {
server.close();
await deferHost.shutdown();
});For a module-local boundary without an explicit shutdown handle:
import { withNodeDefer } from "@use-crux/core/defer/node";
const server = createServer(
withNodeDefer(async (_request, response) => {
defer(() => flushAnalytics());
response.end("ok");
}),
);Inline work remains local to one process. Use named Runtime work when execution must survive a crash or cross Node workers.
See Host support for the complete ladder.