> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Runtimes

> Where the programs in a line run, and how they reach the workspace's files.

A runtime runs the programs in a line. Mirage's own commands (`grep`, `cat`, pipes, redirects) run in the workspace itself; `python3`, `node` and any other program go to the runtime that captures them. Each runtime reaches the workspace's files its own way.

<div className="my-6">
  <img noZoom src="https://mintcdn.com/struktoai/SF883ehuzv5QF1wx/images/runtime-light.svg?fit=max&auto=format&n=SF883ehuzv5QF1wx&q=85&s=5ced5784fb3637565c11f9f8bf92089c" alt="Three kinds of runtime reach one core, the Workspace. In-process engines (monty, wasi, pyodide, quickjs) call it through the VFS bridge. Host programs (local, sandlock) reach it through a FUSE folder. Sandboxes (Docker, Apple Container, smolvm, Daytona, E2B, SSH) reach it over SFTP with sshfs (Docker and E2B, mount_type: ssh), or through FUSE from a Mirage inside the sandbox." className="block dark:hidden w-full" width="1340" height="650" data-path="images/runtime-light.svg" />

  <img noZoom src="https://mintcdn.com/struktoai/SF883ehuzv5QF1wx/images/runtime-dark.svg?fit=max&auto=format&n=SF883ehuzv5QF1wx&q=85&s=914b97f74698e95c22a2ad9bac908b58" alt="Three kinds of runtime reach one core, the Workspace. In-process engines (monty, wasi, pyodide, quickjs) call it through the VFS bridge. Host programs (local, sandlock) reach it through a FUSE folder. Sandboxes (Docker, Apple Container, smolvm, Daytona, E2B, SSH) reach it over SFTP with sshfs (Docker and E2B, mount_type: ssh), or through FUSE from a Mirage inside the sandbox." className="hidden dark:block w-full" width="1340" height="650" data-path="images/runtime-dark.svg" />
</div>

| Runtime | Runs | Where | SDK |
| - | - | - | - |
| `workspace` | Mirage's own commands | in-process | both |
| [`monty`](/home/setup/runtime/monty) | `python3`, a Python subset | in-process | both (default) |
| [`wasi`](/home/setup/runtime/wasi) | `python3`, full CPython on wasmtime | in-process | Python |
| [`pyodide`](/home/setup/runtime/pyodide) | `python3`, full CPython in WebAssembly | in-process | TypeScript |
| [`quickjs`](/home/setup/runtime/quickjs) | `node` and `js` | in-process | both (default) |
| [`local`](/home/setup/runtime/local) | the host's `python3`, and any host program you capture | host | Python, Node |
| [Sandboxes](/home/setup/runtime/sandbox) | native programs | a container, VM, cloud sandbox or SSH machine, or this Linux host with Sandlock | Python, Node |

## Routing

`runtimes` is an ordered list: the first runtime whose `captures` name a program runs it, and `workspace` takes the rest. Without the key, the list is `[monty, quickjs, workspace]` in both SDKs.

```yaml theme={null}
runtimes:
  - monty
  - name: docker
    config:
      container: my-sandbox
      mount_type: ssh
  - workspace
```

An entry is a name, or a mapping with `name`, `captures`, `config` and
`script`. The name is a runtime Mirage ships, one you registered in code, or
a `./file.py:Class` (Python) or `./file.mjs:Class` (TypeScript) reference to
your own runtime. Config keys are snake\_case in YAML for both SDKs, and a
runtime rejects a key it does not know.

A [route policy](/home/policy/route-policy) can pick the runtime per line instead.

## Captures

`captures` lists the programs a runtime takes:

| Entry | Takes |
| - | - |
| A name, such as `python3` or `ffmpeg` | That program |
| `@external` | Every program Mirage does not have itself, such as `gcc`, `ffmpeg`, `uname` or a vendor CLI |
| `*` | The whole line, Mirage's own commands included (sandboxes only) |

| Runtime | Default `captures` |
| - | - |
| `monty`, `wasi`, `pyodide`, `local` | `python3`, `python` |
| `quickjs` | `node`, `js` |
| Sandboxes | `@external` |

* Mirage's own commands (`cat`, `grep`, `sha1sum`), pipes and redirects stay
  in Mirage. `cd`, `export` and `echo` stay even when named.
* `@external` does not take `python`, `python3`, `node` or `js`: Mirage has
  those itself and gives them to the Python or JavaScript runtime in the list.
  Name them to send them somewhere else.
* A program no runtime takes exits 127, `command not found`.
* A name only `@external` takes has no file, so `which`, `command -v` and
  `type` report it missing; running it still works.
* Globs expand against the workspace first (`python3 job.py *.csv` runs
  `python3 job.py a.csv b.csv`), and permission rules judge that argv.

```yaml theme={null}
runtimes:
  - name: docker
    captures: ["python3", "@external"]
    config:
      container: my-sandbox
```

Here `python3 job.py | grep error` runs `python3` in the container and
`grep` in Mirage, and `ffmpeg -i a.mp4 b.webm` runs in the container.

## Files

| Where | Reaches the workspace through | Outside the workspace |
| - | - | - |
| In-process | directly: every file it opens is the workspace's | nothing: no host files, no network, unless a Pyodide `init_module` adds them |
| `local`, Sandlock | a [FUSE folder](/home/setup/fuse) you mount | the host's disk and network; under Sandlock, only the paths you grant |
| Other sandboxes | SFTP and `sshfs` with `mount_type: ssh` (`docker`, `e2b`), or a Mirage inside the sandbox | that sandbox's disk and network |

Mount modes, profiles and policies apply to every file call that reaches the workspace. A host or sandbox runtime also has its own files and network, which they do not cover; only an all in-process list, with no Pyodide `init_module`, keeps agent code inside them.

## Resource limits

`command_limits` apply to a runtime's programs as to any command: past
`timeout_seconds` a program exits 124 (`python3: timed out after Ns`), and
`max_bytes` and `max_lines` cap its output.

```yaml theme={null}
mounts:
  /data:
    vfs: ram
    command_limits:
      python3:
        timeout_seconds: 30
```

The deadline also stops the run in Monty, WASI, Pyodide, `local`, Sandlock
and the Python SDK's QuickJS. The TypeScript SDK's QuickJS and the other
sandboxes only stop waiting, so give untrusted code a finite workload; see
[sandbox timeouts](/home/setup/runtime/sandbox#timeouts).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.