Skip to main content
Version: Next

Runtime Modes Overview

Invowk™ gives you three different ways to execute commands, each with its own strengths. Choose the right runtime for your use case.

The Three Runtimes

RuntimeDescriptionBest For
nativeSystem's default shellDaily development, performance
virtualBuilt-in POSIX shellCross-platform scripts, portability
containerDocker/Podman containerReproducibility, isolation

Quick Comparison

cmds: [
// Native: uses your system shell (bash, zsh, PowerShell, etc.)
{
name: "build native"
implementations: [{
script: "go build ./..."
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
},

// Virtual: uses built-in POSIX-compatible shell
{
name: "build virtual"
implementations: [{
script: "go build ./..."
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
},

// Container: runs inside a container
{
name: "build container"
implementations: [{
script: "go build -o /workspace/bin/app ./..."
runtimes: [{name: "container", image: "golang:1.26"}]
platforms: [{name: "linux"}]
}]
}
]

When to Use Each Runtime

Native Runtime

Use native when you want:

  • Maximum performance
  • Access to all system tools
  • Shell-specific features (bash completions, zsh plugins)
  • Integration with your development environment
{
name: "build"
implementations: [
{
script: "go build ./..."
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}
]
}

Virtual Runtime

Use virtual when you want:

  • Consistent behavior across platforms
  • POSIX-compatible scripts that work everywhere
  • No external shell dependency
  • Simpler debugging of shell scripts
{
name: "build"
implementations: [{
script: """
echo "Building..."
go build -o bin/app ./...
echo "Done!"
"""
runtimes: [{name: "virtual"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Container Runtime

Use container when you want:

  • Reproducible builds
  • Isolated environments
  • Specific tool versions
  • Clean-room execution
{
name: "build"
implementations: [
{
script: "go build -o /workspace/bin/app ./..."
runtimes: [{
name: "container"
image: "golang:1.26"
}]
platforms: [{name: "linux"}]
}
]
}

Multiple Runtimes Per Command

Commands can support multiple runtimes. The first one is the default:

{
name: "build"
implementations: [{
script: "go build ./..."
runtimes: [
{name: "native"}, // Default
{name: "virtual"}, // Alternative
{name: "container", image: "golang:1.26"} // Reproducible
]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Overriding at Runtime

# Use default (native)
invowk cmd build

# Override to virtual
invowk cmd build --ivk-runtime virtual

# Override to container
invowk cmd build --ivk-runtime container

Command Listing

The command list shows available runtimes with an asterisk marking the default:

Available Commands
(* = default runtime)

From invowkfile:
build - Build the project [native*, virtual, container] (linux, macos)

Runtime Selection Flow

The runtime is resolved using a 3-tier precedence model:

  1. CLI flag (--ivk-runtime) — Hard override. Errors if the specified runtime is not compatible with the command on the current platform.
  2. Config default runtime (default_runtime in config) — Soft override. If the config-level default runtime is compatible with the command, use it. Otherwise, silently fall through to Tier 3.
  3. Per-command default — First runtime of the first matching implementation for the current platform.
                    ┌──────────────────┐
│ invowk cmd run │
└────────┬─────────┘

┌──────────▼───────────┐
│ Tier 1: --ivk-runtime│
│ flag provided? │
└──────────┬───────────┘

┌──────────────┴──────────────┐
│ Yes │ No
▼ ▼
┌─────────────────────┐ ┌──────────────────────┐
│ Use specified │ │ Tier 2: config │
│ runtime (hard error │ │ default_runtime set? │
│ if incompatible) │ └──────────┬───────────┘
└─────────────────────┘ │
┌────────────┴────────────┐
│ Yes & compatible │ No / incompatible
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ Use config default │ │ Tier 3: per-command │
│ runtime │ │ default (first │
└─────────────────────┘ │ matching runtime) │
└─────────────────────┘

Dependency Validation

Dependencies are validated according to the runtime:

RuntimeDependencies Validated Against
nativeHost system's shell and tools
virtualBuilt-in shell with core utilities
containerContainer's shell and environment

This means a tools dependency like go is checked:

  • native: Is go in the host's PATH?
  • virtual: Is go available in the virtual shell environment (built-ins and system PATH)?
  • container: Is go installed in the container image?

Next Steps

Dive deeper into each runtime: