← All examples
Shell environment
nvmfnmNode.js

Run services with a specific Node version (nvm / fnm)

You point Runyard at your project, it starts the service, and you get command not found: node or worse, the system Node (the wrong version) runs and your build fails. The cause is the same in both cases.

The trick

nvm and fnm are shell functions, not standalone binaries. They install themselves by adding init code to your .zshrc or .bashrc. Runyard's spawned environment is sanitized and does not load those files, so neither tool initializes and the node they expose is invisible.

There are two clean fixes, each with tradeoffs.

Option A: Pin a Node version in paths

Add the exact node binary directory to Runyard's paths array. Works for any service. No shell wrapping.

{
  "paths": [
    "~/.nvm/versions/node/v22.0.0/bin",
    "/opt/homebrew/bin"
  ],
  "tools": [
    {
      "name": "API",
      "type": "service",
      "directory": "~/Code/your-project",
      "startCommands": [{
        "label": "Dev",
        "command": "npm",
        "args": ["run", "dev"],
        "startupCheck": "http://localhost/health",
        "startupFallbackPort": 3000
      }]
    }
  ]
}

Pros: Simple. No shell startup overhead. Works the same for all services that need this Node.

Cons: The path is hard-coded. When you upgrade Node, you have to edit config.json to bump the version. Different projects on different Node versions need different paths arrays per tool (use paths at the tool level with pathsOverride: false to merge).

Let your shell init files do their job. Runyard runs the command, your shell sources .zshrc, nvm/fnm initialize, and .nvmrc / .node-version is respected automatically.

{
  "name": "API",
  "type": "service",
  "directory": "~/Code/your-project",
  "startCommands": [{
    "label": "Dev",
    "command": "/bin/zsh",
    "args": ["-lc", "npm run dev"],
    "startupCheck": "http://localhost/health",
    "startupFallbackPort": 3000
  }]
}

Pros: Auto-switches Node version based on .nvmrc / .node-version. No config drift when you upgrade Node. Works identically to running npm run dev in your terminal.

Cons: Slightly slower startup (a few hundred milliseconds for shell init). All your .zshrc runs every time, including unrelated prompts and aliases.

Why this works

Prerequisites