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>;
}programis the exact Runtime program being executed.runtimeis the resolved executable Runtime owned by the worker.closedresolves 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.timeoutMsdefaults 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.