> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.islo.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.islo.dev/_mcp/server.

# Setup scripts

> How Islo runs your setup commands after creating a sandbox.

Setup scripts prepare the sandbox used by a [Machine](/concepts/machines) or direct CLI session. Configure them when the Agent needs tools that are absent from the base environment.

Setup scripts prepare a sandbox after sources are cloned but before you start using it — installing language runtimes, syncing dependencies, building tools. There are two equivalent forms in `islo.yaml`: a single `setup_script` string or a named-step `setup_scripts` array.

## When Setup Runs

Setup runs server-side as part of sandbox creation:

```
islo use (new sandbox)
    │
    ├── Clone sources (from `sources:` in islo.yaml)
    │
    └── Run setup_script / setup_scripts
```

After setup completes, the sandbox is ready and your shell, command, or agent session starts.

Setup runs once during sandbox creation. Reconnecting to an existing sandbox (`islo use <existing-name>`) does not re-run setup — edit the script and recreate the sandbox to pick up new steps.

## Execution Environment

| Property          | Value                                 |
| ----------------- | ------------------------------------- |
| User              | `islo` (non-root)                     |
| Working directory | `/workspace`                          |
| Shell             | `bash`                                |
| Sources           | Already cloned under `/workspace/...` |

If you need root, set `user: root` in `islo.yaml`. If you need a different working directory for your shell or agent session, set `workdir:` — that affects the session, not the setup script.

## `setup_script` vs `setup_scripts`

Both fields produce the same result; pick whichever reads better for your project.

**`setup_script`** — one shell block:

```yaml
setup_script: |
  curl -LsSf https://astral.sh/uv/install.sh | sh
  export PATH="$HOME/.local/bin:$PATH"
  uv sync
```

**`setup_scripts`** — named, ordered steps:

```yaml
setup_scripts:
  - name: Install uv
    script: |
      curl -LsSf https://astral.sh/uv/install.sh | sh
      export PATH="$HOME/.local/bin:$PATH"
  - name: Sync Python deps
    script: uv sync
```

Named steps appear individually in setup output and exec logs, which makes failures easier to attribute. Prefer `setup_scripts` for anything more than a few lines.

## Adding Steps with `islo add`

`islo add` writes entries into `setup_scripts:` using built-in recipes.

```bash
islo add                                       # Interactive: detect tools, pick which to add
islo add python 3.12                           # Add the Python recipe pinned to 3.12
islo add node 20                               # Add the Node recipe pinned to 20
islo add --script 'apt-get install -y curl'   # Add a custom one-line step
```

Edit `islo.yaml` directly when you need something the recipes don't cover.

## Common Patterns

### Python + uv

```yaml
setup_script: |
  curl -LsSf https://astral.sh/uv/install.sh | sh
  export PATH="$HOME/.local/bin:$PATH"
  uv sync
```

### Node + pnpm

```yaml
setup_script: |
  corepack enable
  pnpm install --frozen-lockfile
```

### Multi-language with named steps

```yaml
setup_scripts:
  - name: Install Rust
    script: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
  - name: Install Node deps
    script: |
      corepack enable
      pnpm install
  - name: Build
    script: cargo build --release
```

### Install an agent CLI

```yaml
setup_scripts:
  - name: Install Claude Code
    script: curl -fsSL https://claude.ai/install.sh | DISABLE_AUTOUPDATER=1 bash
```

## Templates

`islo init --template <name>` writes a starter `islo.yaml` with a sensible `setup_script` for the language. Run `islo init --list` to see what's available; current options include `default`, `python`, `node`, `rust`, `go`, and `fullstack`.