Skip to main content
Version: 0.14.0

Runtime Modes Overview

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

The Four Runtimes

RuntimeDescriptionBest For
nativeSystem's default shellDaily development, performance
virtual-shBuilt-in POSIX shellCross-platform shell scripts, portability
virtual-luaBuilt-in Lua interpreterCross-platform Lua automation
containerDocker/Podman containerReproducibility, isolation

Quick Comparison

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

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

// Container: runs inside a container
{
name: "build container"
implementations: [{
script: {content: "echo building in container"}
runtimes: [{name: "container", image: "debian:stable-slim"}]
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: {content: "go build ./..."}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}
]
}

Virtual-Sh Runtime

Use virtual-sh when you want:

  • Consistent behavior across platforms
  • POSIX-compatible scripts that work everywhere
  • No external shell dependency (the interpreter is built in, and scripts can call explicitly allowed host binaries)
  • Simpler debugging of shell scripts
caution

The virtual-sh runtime is not a sandbox. Host binaries are denied unless explicitly listed with allowed_binaries. For execution isolation, use the container runtime.

{
name: "build"
implementations: [{
script: {content: """
echo "Building..."
go build -o bin/app ./...
echo "Done!"
"""}
runtimes: [{name: "virtual-sh", allowed_binaries: ["go"]}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Virtual-Lua Runtime

Use virtual-lua when you want:

  • Portable Lua automation without requiring a host Lua binary
  • Structured scripts with tables, functions, and module-local require
  • Path-validated file I/O through Invowk's virtual safety harness
  • Explicit bridge calls for utilities and allowed host binaries
caution

The virtual-lua runtime is not a sandbox. Allowed host binaries still run as native host processes. For execution isolation, use the container runtime.

{
name: "hello-lua"
implementations: [{
script: {content: """
print("Hello from virtual-lua")
print("workdir: " .. invowk.path("@work"))
"""}
runtimes: [{name: "virtual-lua"}]
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: {content: "echo 'Hello from container' && ls /workspace"}
runtimes: [{
name: "container"
image: "debian:stable-slim"
}]
platforms: [{name: "linux"}]
}
]
}

Multiple Runtimes Per Command

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

{
name: "build"
implementations: [
{
script: {content: "go build ./..."}
runtimes: [
{name: "native"}, // Default
{name: "virtual-sh", allowed_binaries: ["go"], binary_lookup_mode: "host"}, // Alternative
]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
},
{
script: {content: "echo building in container"}
runtimes: [
{name: "container", image: "debian:stable-slim"} // Reproducible
]
platforms: [{name: "linux"}] // Container runtime is Linux-only
},
]
}

Overriding at Runtime

# Use default (native)
invowk cmd build

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

# 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-sh, 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

Root, command, and implementation-level depends_on entries are always validated against the host system, regardless of the selected runtime. Runtime-level depends_on is only available in container runtime configs, where it validates dependencies inside the container environment.

ScopeDependencies Validated Against
Root / command / implementation depends_onHost system
Container runtime depends_onContainer image environment

This means a command-level tools dependency like go checks whether go is available on the host. To check whether go is installed inside a container image, put that dependency inside the container runtime block.

Next Steps

Dive deeper into each runtime: