Crux
API Reference@use-crux/core

Runtime program and worker

API reference for immutable Runtime programs and the self-hosted execution worker lifecycle.

import {
  createRuntimeProgram,
  createRuntimeWorker,
  type RuntimeProgram,
  type RuntimeProgramTarget,
  type RuntimeWorker,
} from "@use-crux/core/runtime";

Most applications use the generated program through crux runtime worker. The APIs on this page support generated hosts, tests, and advanced hand-written hosts.

RuntimeProgram

interface RuntimeProgram {
  readonly manifestHash: string;
  readonly targets: readonly RuntimeProgramTarget[];
  readonly targetDefinitions: readonly RuntimeProgramTargetDefinition[];
  readonly effectTargets: readonly RuntimeEffectTarget[];
  readonly generationModels: readonly GenerationModel[];
  readonly transports: readonly RuntimeManagedTransportBinding[];
}

A provider-neutral declaration of executable targets, exact Effect recovery target identities, statically declared generation models, and managed-transport bindings for one project with shallow structural immutability. manifestHash is the SHA-256 hash of the canonical program declaration. It is distinct from the generated artifact hash that binds program.ts to the exact bytes of manifest.json.

createRuntimeProgram() freezes the program, its copied arrays, and detached transport records, while target object references remain the supplied references. The object does not contain live clients, credentials, Requests, mutable registration, or configuration lookup. Generated programs pair each target with its exact Project Index definition identity and fingerprint. Application Work acceptance pins that metadata together with manifestHash. Durable Agent Sessions select models only from generationModels and pin { definitionId, fingerprint } in Session state.

createRuntimeProgram(options)

interface CreateRuntimeProgramOptions {
  readonly targets: readonly (
    | RuntimeProgramTarget
    | {
        readonly target: RuntimeProgramTarget;
        readonly definition: {
          readonly id: string;
          readonly fingerprint: string;
        };
    }
  )[];
  readonly effectTargets?: readonly RuntimeEffectTargetDefinition[];
  readonly generationModels?: readonly GenerationModel[];
  readonly transports: readonly RuntimeManagedTransportBinding[];
}

declare function createRuntimeProgram(
  options: CreateRuntimeProgramOptions,
): RuntimeProgram;

Purely validates, canonicalizes, hashes, and freezes one program. It performs no I/O or discovery. Generated code calls this same function.

Validation rejects duplicate target or binding identities and one adapter identity declared with incompatible providers. Effect recovery targets must be recoverable definitions and are keyed by exact (id, version). generationModels are ordered and fingerprinted into the manifest; Session construction rejects a selected model that is absent from this list with GENERATION_MODEL_NOT_STATIC.

import { createRuntimeProgram, durableTask } from "@use-crux/core/runtime";

const rebuild = durableTask("rebuild", {
  run: async (input: { documentId: string }) => {
    await rebuildDocument(input.documentId);
  },
});

export const runtimeProgram = createRuntimeProgram({
  targets: [rebuild, supportAgent],
  generationModels: [supportModel],
  transports: [],
});

createRuntimeWorker(options)

interface CreateRuntimeWorkerOptions<TStore extends RuntimeStoreAdapter> {
  readonly runtime: InProcessRuntimeEngineDefinition<TStore>;
  readonly program: RuntimeProgram;
  readonly pollIntervalMs?: number;
}

declare function createRuntimeWorker<TStore extends RuntimeStoreAdapter>(
  options: CreateRuntimeWorkerOptions<TStore>,
): RuntimeWorker<TStore>;

Creates and immediately starts a process-local worker. It resolves executable targets only from program.targets, disables composer-owned maintenance, and runs one immediate serial maintenance loop. Each pass runs retention, claims interrupted Effect rollback scopes through the Effects store port, then drains managed transport envelopes. Effect recovery resolves only exact targets from program.effectTargets and executes the store-reconstructed reverse plan. pollIntervalMs defaults to the composer's maintenance interval, then 1000 ms, and must be positive and finite.

runtime must be an in-process definition such as node(), not a host-bound definition. The low-level API can use any conforming Runtime store, but safe cross-process single-worker operation requires the store's durable maintenanceOwnership port. The first-party CLI requires it and currently supports node({ store: postgres() }).

Creation synchronously rejects unresolved or duplicate program targets and a duplicate owner on the same store object and namespace. Durable ownership is asynchronous: failure rejects worker.closed before a maintenance tick runs.

RuntimeWorker

interface RuntimeWorker<TStore extends RuntimeStoreAdapter> {
  readonly program: RuntimeProgram;
  readonly runtime: ResolvedRuntimeEngine<TStore>;
  readonly closed: Promise<void>;
  readonly stop: (options?: { timeoutMs?: number }) => Promise<void>;
}
  • program is the exact Runtime program being executed.
  • runtime is the resolved executable Runtime owned by the worker.
  • closed resolves after a clean stop and rejects after fatal maintenance, ownership release failure, or a stop timeout.
  • stop() is idempotent. It stops future ticks, waits for acquisition or the active tick, disposes the Runtime, and releases ownership. timeoutMs defaults to 10,000 and must be positive and finite.

A timeout rejects without claiming external work was cancelled. Ownership is released after the still-active operation eventually settles.

Ownership contract

Only one worker may maintain a given store and namespace in a process. When a store implements maintenanceOwnership, only one may maintain that namespace across processes. Different namespaces can run concurrently.

The worker acquires local ownership before returning and durable ownership before its first tick. It releases both on clean stop or fatal failure. Replace a worker only after await worker.stop() or after the prior process exits. An ownership adapter may expose lease.lost, a promise that rejects when its backing session is lost; the worker treats that rejection as fatal and closes.

Generated program loading

The loader used by crux runtime worker is internal. It reads .crux/generated/runtime/program.ts and manifest.json, validates manifest version and shape, imports the program with an 8-second bound, compares the manifest byte hash, validates the exported program shape, and compares ordered target definitions and Effect (id, version) identities. Users regenerate artifacts rather than calling this loader.

loadRuntimeWorkerHost({ root, configPath? }) from @use-crux/indexer/host/runtime is a Crux-owned compiler/build host contract, not an application SDK surface. It loads project config in Runtime-rich indexing mode and returns only an in-process Runtime whose store has durable maintenance ownership. It reports config import, missing ownership, and missing Runtime errors with remediation. It does not load the generated program or start a worker.

On this page