Skip to content

Environment variables

mvmforge reads a small, documented set of environment variables. They fall into three groups: SDK invocation, substrate invocation, and pin override.

SDK invocation

These variables tell mvmforge emit and mvmforge up which language runtimes and SDK entrypoints to use when subprocessing.

VariableDefaultPurpose
MVMFORGE_PYTHON_BINpythonPython interpreter for .py entries. Should be a Python that has the mvmforge package importable — typically the venv-managed one at sdks/python/.venv/bin/python during dev.
MVMFORGE_NODE_BINnodeNode interpreter for .ts entries. Must be Node 22.6+ (for --experimental-strip-types).
MVMFORGE_TS_MAINsdks/typescript/src/main.tsThe TypeScript SDK entrypoint that the host invokes via node --experimental-strip-types.
MVMFORGE_IR_OUT(set by host)Set by the host when invoking the SDK. The SDK writes canonical IR to this path. Users don’t normally set this directly.
MVMFORGE_EMITTING(set by host)Set to "1" by the host when invoking the SDK as the emit subprocess. The runtime SDK reads it on Layer-3 calls (f.remote(...), mvmforge.session(...)) and raises EmittingContextError if set — prevents build-time recursion where an entry module tries to call into a VM that doesn’t exist yet. Per ADR-0010 §2 (proposed). Users should never set this directly.

Substrate invocation

These tell mvmforge up how to reach mvmctl.

VariableDefaultPurpose
MVMFORGE_MVM_BIN(search PATH for mvm)The mvmctl binary. The project name is mvm; the binary is named mvmctl. Either works as a value.

Pin override

VariableDefaultPurpose
MVMFORGE_MVM_FLAKE_URL(build-time pin to github:auser/mvm/<rev>?dir=nix/guest-lib)Override the mvm flake input rendered into generated flake.nix. Useful for local-checkout development: path:/abs/path/to/mvm/nix/guest-lib.

Note: setting this breaks cross-machine byte-reproducibility — same-machine reproducibility holds as long as the override value doesn’t change. Per ADR-0007 §6.

just recipe variables

These are read by recipes in the Justfile rather than by mvmforge itself.

VariableRead byPurpose
MVMFORGE_MVM_REPOjust real-mvm-check, just real-mvm-upPath to a local mvm checkout. The recipes invoke mvmctl via cargo run --manifest-path "$MVMFORGE_MVM_REPO/Cargo.toml", so no separate install is needed.
MVMFORGE_UP_ARGSjust real-mvm-upExtra mvmctl up flags forwarded after --, e.g. '--hypervisor apple-container --name foo'.

Test variables

For the fake-mvm shim at tests/fixtures/fake-mvm:

VariableRead byPurpose
MVMFORGE_FAKE_MVM_RECORDfake-mvm shimPath to append invocation details for test assertions.
MVMFORGE_FAKE_MVM_EXITfake-mvm shimExit code (default 0). Used to test exit-code propagation.
MVMFORGE_FAKE_MVM_STDOUTfake-mvm shimIf set, echoed to stdout before exit.

What mvmforge does not read

  • MVMFORGE_* variables not listed above.
  • NIX_* variables. mvmforge compile does not invoke Nix.
  • LANG, LC_*, TZ. Compile output is locale- and timezone-independent for reproducibility.
  • The user’s PATH for anything other than mvmctl discovery (when MVMFORGE_MVM_BIN is unset).

If you set anything else expecting mvmforge to honor it, it won’t. File an issue if you have a use case.