Project runtimes

Pin runtimes per repository with a small, committed file. Every command in the project then uses exactly those versions.

Pinning

shell
jrt pin node@20 python@3.12     # pin several runtimes at once
jrt current                      # pins in effect for this directory

jrt pin writes (or updates) .jrt.toml at the project root:

.jrt.toml
[runtimes]
node = "20"
python = "3.12"

Commit this file. Anyone who clones the repo and has jrt gets the same runtimes. A pin can be a major (20), a minor (3.12) or an exact version; vendor-prefixed Java versions such as temurin-17 are kept as written.

Supported runtimes

RuntimeExample pin
Node.jsnode@20
Pythonpython@3.12
Gogo@1.26
Rustrust@1.85
.NET SDKdotnet@8
Javajava@temurin-17
Bunbun@1.4
Denodeno@2.9
Rubyruby@3.4

Installing runtimes

shell
jrt runtime install node@20
jrt runtime install java@temurin-17
jrt runtime list                 # everything installed
jrt runtime list python          # one runtime

Versions are installed side by side under JRT_HOME and never replace one another.

Running project commands

jrt exec -- runs any command with the project’s pinned runtimes on PATH:

shell
jrt exec -- node server.js
jrt exec -- python -m pytest
jrt exec -- go test ./...
jrt exec -- cargo build --release

The command’s exit code is passed through unchanged, so jrt is safe to use in scripts and CI.

One-off runtimes

jrt x runs a single command on a specific runtime without pinning anything:

shell
jrt x node@22 -- node -v
jrt x python@3.13 -- python -c "import sys; print(sys.version)"

Package managers (Node)

jrt treats package.json#packageManager as the project’s package-manager pin, without relying on Corepack:

package.json
{
  "packageManager": "pnpm@10.17.1"
}
shell
jrt exec -- pnpm install         # exactly pnpm 10.17.1 on the pinned Node
  • Modern Yarn runs from @yarnpkg/cli-dist; Yarn Classic uses yarn.
  • Calling a different manager than the pinned one is refused, so a stray npm install cannot rewrite a pnpm lockfile.
  • The package manager’s own Node engines requirement is checked before it runs.