Crux
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.

On this page

No Headings