Environment variables

The complete reference for the user-facing CRUFT_* environment variables, the ones meant to be set by a person, grouped by what they tune: the runtime and garbage collector, Node/Deno/TypeScript compatibility, module loading, capabilities, the package manager, the node wrapper, diagnostics, workers, and the handful of JIT knobs. Each entry states its values, default, and effect.

The cruft binary reads CRUFT_* environment variables to tune the runtime, the garbage collector, compatibility, module loading, the capability system, the package manager, the front door, and diagnostics. This page is the complete reference for the user-facing variables: the ones a person sets. Each entry states the accepted values, the default when unset, and the effect.

Values are read at process start. Where a variable is a boolean flag, the runtime checks for presence (any value, including empty, counts as "on") unless an explicit value grammar is listed. A variable read through the compatibility helper also accepts its pre-rename CRUFTLESS_* spelling as a fallback.

Not covered here, by design: the large family of internal engine-development knobs, the LeJIT per-optimization gates, per-builtin trace and counter flags, phase and timing profilers, and the time-travel and semantic-breakpoint debuggers. They exist for engine development, are not part of the stable surface, and may change or vanish without notice. The five genuinely tunable JIT knobs that are user-facing appear under JIT tuning below.

Runtime and garbage collection

VariableDefaultEffect
CRUFT_GC_HEADROOM4.0Post-sweep heap-growth multiplier before the next collection (a float, e.g. 1.5, 2.0, 4). Higher collects less eagerly (more RSS, less CPU); lower tightens RSS. Clamped to a 1.1x floor so a mistuned value cannot force collect-on-every-allocation. Unset or invalid falls back to 4.0.
CRUFT_GC_TARGET_MBunset (disabled)Soft whole-process RSS target in megabytes. When set, headroom auto-tunes down toward the 1.1x floor as RSS rises toward the target, so aggregate RSS self-bounds near it. 0, negative, or invalid disables it; on platforms where RSS is unreadable the auto-tune disables itself.
CRUFT_GC_EXTERNAL_MB64Megabytes of external backing store (ArrayBuffer bytes and similar) whose churn forces a collection, so large off-heap allocation still triggers GC.
CRUFT_GC_STRESSunset (off)Presence forces a collection at a bounded allocation cadence rather than at the adaptive threshold. A soundness-testing knob; it slows execution, and a program still runs to completion with it set.
CRUFT_MICROTASK_BUDGETunset (unlimited)Caps microtasks drained per event-loop turn (a positive integer). Overflowing the cap throws a TypeError (microtask budget exceeded). 0, negative, or non-numeric leaves it unlimited. The agent sandbox uses this to bound runaway promise loops.
CRUFT_MAIN_AGENT_CAN_BLOCKruntime default0/false clears the main agent's ability to block (Atomics.wait on the main thread); any other value sets it. Advanced; primarily a conformance knob.

Deviations and compatibility tolerance

CRUFT_DEVIATIONS is the umbrella switch for the Node-compat deviation set. Each CRUFT_DEVIATION_* variable overrides the umbrella for one behavior, in either direction (a per-flag 1/true/on forces it on; 0 forces it off).

VariableDefaultEffect
CRUFT_DEVIATIONSautoMaster switch. off/0/false/empty is spec-pure and host-independent; node/on/1/true enables every deviation; auto enables them only when a node_modules directory exists at or above the entry. Unset or unrecognized falls through to auto.
CRUFT_DEVIATION_LEGACY_CALLER_ARGUMENTSumbrellaOn: non-strict functions expose live .caller/.arguments instead of the spec-pure poison pill.
CRUFT_DEVIATION_NO_PROPER_TAIL_CALLSumbrellaOn: disables ECMAScript proper tail calls, matching Node/V8 stack-growth behavior.
CRUFT_DEVIATION_DATE_LOCAL_TZumbrellaOn: Date and Intl default to the host system time zone. Off (spec-pure default): UTC, for reproducibility.
CRUFT_DEVIATION_NODE_ERROR_STACKumbrellaOn: errors carry an own writable stack data property (Node/V8 shape) rather than the spec's prototype accessor.
CRUFT_TOLERATEnoneSelectively tolerates named Node-isms without the full umbrella. all/1, or a comma list of to-object-coerce-nullish, function-not-constructor-relax; 0/empty is off.

Compatibility and runtime persona

VariableDefaultEffect
CRUFT_DENO_COMPATonInstalls the Deno.* global surface. 0/false disables it (typeof Deno becomes "undefined").
CRUFT_CJS_INTEROPNode policyChooses the CommonJS-to-ESM namespace synthesis policy. bun selects Bun's policy; any other value uses Node's.
CRUFT_NODEnodePath or command name Cruft invokes when it needs the real Node binary (wrapper backend, npm lifecycle spawns).
CRUFT_NODE_VERSION26.3.0Overrides the reported Node version (process.version, process.versions.node) so framework engine gates clear. Accepted only if it parses as X.Y.Z; otherwise the built-in persona stands.
CRUFT_NODE_FORKunset (internal)Marker Cruft sets when it forks a child through the IPC path; presence makes a .js entry take the CommonJS route. Set by the runtime, not normally by a user.
CRUFT_NO_WARNINGSunset (warnings on)Presence suppresses process-warning lines on stderr (deprecations and similar), mirroring Node's NODE_NO_WARNINGS.
CRUFT_TS_COMPAT / CRUFT_TS_COMPAT_ERASUREoff1/true/yes/on enables erasure of TypeScript angle-bracket type assertions in non-.tsx files.
CRUFT_TS_TRANSFORMoff1/true/yes/on routes TypeScript through the full transform (enums, parameter properties) instead of erasure-only.

Module loading

VariableDefaultEffect
CRUFT_FORCE_MODULEunsetPresence forces the entry to parse as an ES module, overriding extension and source sniffing. Loses to CRUFT_FORCE_SCRIPT when both are set.
CRUFT_FORCE_SCRIPTunsetPresence forces the entry to parse as a classic script (CommonJS), overriding all detection. Wins over CRUFT_FORCE_MODULE and the CJS-wrap heuristic.
CRUFT_PRELOADunsetPath to a script run in the realm before the entry file; its top-level declarations become globals visible to the entry. The -r/--require flag uses the same mechanism. A read or eval error aborts with a non-zero exit.

Capabilities and security

VariableDefaultEffect
CRUFT_CAPS_MODEcompatCapability enforcement mode when no CLI flag (--audit/--sealed-deps/--sealed) is given. Recognized: compat/0 (no enforcement), audit/1 (record only), sealed-deps/2, sealed/3 (enforce). Unknown values keep compat.
CRUFT_ALLOW_NET_LOOPBACKdeny1/true/yes permits loopback network access under the capability system without an explicit grant. Equivalent to --allow-net-loopback.
CRUFT_ENV_ALLOWnoneUnder sealed modes, a comma-separated whitelist of environment-variable names that user code may read through process.env.
CRUFT_STDIO_ALLOWnoneUnder sealed modes, a comma list containing stdout and/or stderr granting user code permission to write those streams.
CRUFT_CAPS_VERBOSEunset (off)Presence prints capability-closure diagnostics to stderr.

Package manager

VariableDefaultEffect
CRUFT_REGISTRYhttps://registry.npmjs.orgnpm registry base URL for cruft install. A project registry-policy file overrides it.
CRUFT_REGISTRY_TOKENnoneBearer token for registry authentication. Preferred over CRUFT_NPM_TOKEN.
CRUFT_NPM_TOKENnoneBearer token for registry authentication (fallback when CRUFT_REGISTRY_TOKEN is unset).
CRUFT_STORE$HOME/.cruft/storeRoot of the global content-addressed package store that installs hard-link from.
CRUFT_INSTALL_MODElinked (hardlinks)node_modules materialization. Default links from the store (shared inodes). isolated, npm, or copy select independent byte-copies at the cost of disk and copy time; any other value keeps linked mode.
CRUFT_PM_CONCURRENCY16Cap on concurrent resolve/fetch workers during install. Non-numeric or unset uses 16.
CRUFT_PM_LEGACY_PEER_DEPSunset (off)Presence is the --legacy-peer-deps escape hatch: warn-and-pick instead of failing on an unsatisfiable peer.
CRUFT_PM_NO_PEERSunset (off)Presence skips automatic peer-dependency installation entirely.
CRUFT_PM_ALLOW_SHA1_SHASUMunset (off)Presence accepts legacy SHA-1 tarball shasums during integrity checking.

Front door and the node/npm wrapper

These govern cruft wrap and the persistent node/npm/npx shim layer.

VariableDefaultEffect
CRUFT_WRAP_HOME$HOMEHome directory the wrapper uses to locate its shim state. Falls back to $HOME/%USERPROFILE%; if neither is set the wrapper errors.
CRUFT_WRAP_PROFILEplatform shell profilePath of the shell profile the wrapper edits to install its managed PATH block.

Diagnostics and logging

VariableDefaultEffect
CRUFT_DIAGNOSTICSpublic (redacted)Diagnostic disclosure mode. structural/developer/debug show full internal detail; any other value keeps redacted public diagnostics. Also settable via CLI flag.
CRUFT_DIAGNOSTIC_MODEpublicAlias fallback for CRUFT_DIAGNOSTICS when that is unset.
CRUFT_DIAGNOSTIC_LOGnoneFile path for the diagnostic log artifact.
CRUFT_DIAGNOSTIC_ARTIFACTnoneAlias fallback for CRUFT_DIAGNOSTIC_LOG when that is unset.
CRUFT_UNHANDLED_REJECTIONwarn + abortDisposition for an unhandled promise rejection. warn diagnoses without aborting; none/silent stays quiet; any other value (the default) diagnoses and aborts non-zero.
CRUFT_REPL_HISTORY$HOME/.cruft_repl_historyREPL persistent history file (mirrors Node's NODE_REPL_HISTORY). An empty value disables history.
CRUFT_REPL_PREVIEWon (TTY)Inline REPL preview / ghost completion. 0 disables it.
CRUFT_PROFILEunset (off)Advanced: presence prints a phase-timing profile (modules, parse, eval) to stderr after the run.
CRUFT_STARTUP_PROFILEunset (off)Advanced: presence prints per-phase startup timing to stderr.
CRUFT_BOOT_TRACEunset (off)Advanced: presence prints a cold-start boot trace with a ranked intrinsic-install breakdown.
CRUFT_ALLOC_TRACKunset (off)Advanced: presence installs a heap-attribution allocator that dumps a peak histogram on exit. Adds overhead.
CRUFT_TLS_DEBUGunset (off)Advanced: presence enables verbose TLS handshake debug output on stderr.

Workers

VariableDefaultEffect
CRUFT_WORKER_REPLY_TIMEOUT_MS120000Wall-clock deadline in milliseconds for a worker host-call reply.

CRUFT_WORKER and CRUFT_WORKER_DATA are set by the runtime when it spawns a worker child (to wire parentPort and pass workerData); they are internal plumbing, not variables you set yourself.

JIT tuning

The runtime's JIT ships on by default. These five knobs tune it; every other CRUFT_LEJIT_* / CRUFT_OSR_* variable is an internal development gate and is not a supported surface.

VariableDefaultEffect
CRUFT_JIT_DISABLEoff (JIT on)1/true disables the JIT entirely and runs the pure interpreter. Useful for troubleshooting or A/B performance comparison.
CRUFT_JIT_THRESHOLD2000Call count before a function tiers up to the JIT. Lower compiles sooner (faster warmup, more compile time).
CRUFT_OSR_THRESHOLD1000Loop back-edge count before a hot loop is OSR-compiled mid-execution. The loop-level companion to CRUFT_JIT_THRESHOLD.
CRUFT_JIT_OPTspeed (release)Cranelift optimization level for generated code: none, speed, or speed_and_size.
CRUFT_IC_INLINEonInline (in-codegen) property and array inline caches. 0/false falls back to helper-based inline caches. On by default when the runtime's layout self-check passes.

Paths

VariableDefaultEffect
CRUFT_CPX_CACHE$HOME/.cruft/cpxCache root for cpx packaged-executable materialization.

Notes

  • Per-flag deviation overrides win over the umbrella. A CRUFT_DEVIATION_* variable forces its behavior on (1/true/on) or off (0) regardless of CRUFT_DEVIATIONS.
  • Presence versus value. Where an entry says "presence", only being set matters; the value is not parsed. Where a value grammar is given, only the listed values have the stated effect.
  • Legacy spelling. Variables read through the compatibility helper also accept the pre-rename CRUFTLESS_* name as a fallback.