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

# Basic usage

> Day-to-day SmolVM workflows — create sandboxes, run shell commands, check exit codes and output, and handle errors using the Python SDK.

This page covers the everyday operations you need to work with SmolVM: creating a sandbox, running commands inside it, reading the output, and handling errors. If you have not installed SmolVM yet, start with the [quickstart](/smolvm/quickstart).

## Quick start

The simplest way to use SmolVM is the auto-configuration mode:

```python theme={null} theme={null}
from smolvm import SmolVM

with SmolVM() as vm:
    result = vm.run("uname -r")
    print(result.stdout)
```

When you create a `SmolVM()` with no arguments, it automatically:

* Generates SSH keys (stored in `~/.smolvm/keys/`)
* Builds an Alpine Linux image with SSH pre-configured
* Creates a VM with sensible defaults (512MB RAM, 1 vCPU)
* Starts the VM when entering the context manager

## Creating a sandbox

You can create a sandbox with sensible defaults or customize the configuration.

<Tabs>
  <Tab title="Auto-config (Recommended)">
    ```python theme={null} theme={null}
    from smolvm import SmolVM

    # Minimal configuration
    with SmolVM() as vm:
        print(f"VM running at {vm.get_ip()}")

    # Custom memory and disk size
    with SmolVM(memory=1024, disk_size=1024) as vm:
        print(f"VM ID: {vm.vm_id}")
    ```
  </Tab>

  <Tab title="Manual Configuration">
    ```python theme={null} theme={null}
    from smolvm import SmolVM, VMConfig
    from smolvm.build import ImageBuilder, SSH_BOOT_ARGS

    # Build custom image
    builder = ImageBuilder()
    kernel, rootfs = builder.build_alpine_ssh()

    # Create VM with explicit config
    config = VMConfig(
        vm_id="my-vm",
        vcpu_count=2,
        memory=1024,
        kernel_path=kernel,
        rootfs_path=rootfs,
        boot_args=SSH_BOOT_ARGS,
    )

    with SmolVM(config) as vm:
        result = vm.run("echo 'Hello from SmolVM'")
        print(result.output)
    ```
  </Tab>
</Tabs>

## Running commands

The `run()` method executes commands via SSH and returns a `CommandResult` object:

```python theme={null} theme={null}
from smolvm import SmolVM

with SmolVM() as vm:
    # Basic command execution
    result = vm.run("ls -la /")
    print(result.stdout)  # Command output
    print(result.exit_code)  # Exit status (0 = success)
    print(result.ok)  # True if exit_code == 0

    # Commands with custom timeout
    result = vm.run("sleep 10", timeout=60)

    # Handle command failures
    result = vm.run("exit 1")
    if not result.ok:
        print(f"Command failed: {result.stderr}")
```

### Shell modes

SmolVM supports two command execution modes:

```python theme={null} theme={null}
# Login shell mode (default) - runs through guest login shell
result = vm.run("echo $HOME", shell="login")

# Raw mode - executes command directly with no shell wrapping
result = vm.run("/bin/ls", shell="raw")
```

## VM properties

Access VM information through properties:

```python theme={null} theme={null}
with SmolVM() as vm:
    print(vm.vm_id)        # VM identifier
    print(vm.status)       # Current state (VMState.RUNNING)
    print(vm.get_ip())     # Guest IP address
    print(vm.info)         # Full VMInfo object (cached)
    print(vm.data_dir)     # State directory path

    # Refresh cached info from state store
    vm.refresh()
    print(vm.info.status)
```

## Checking SSH capability

Not all VM images support command execution. You can check before running commands:

```python theme={null} theme={null}
with SmolVM() as vm:
    if vm.can_run_commands():
        result = vm.run("whoami")
        print(result.output)
    else:
        print("This VM does not support SSH command execution")
```

<Note>
  Command execution requires the VM to be booted with `init=/init` in the boot arguments. All auto-configured VMs and images built with `ImageBuilder` include this by default.
</Note>

## Getting SSH connection details

Retrieve SSH commands for manual connection:

```python theme={null} theme={null}
with SmolVM() as vm:
    ssh_cmds = vm.ssh_commands()
    print(ssh_cmds["direct"])     # SSH to guest IP
    print(ssh_cmds["localhost"])  # SSH via localhost (if forwarded)
```

## Error handling

SmolVM raises specific exceptions for different failure scenarios:

```python theme={null} theme={null}
from smolvm import SmolVM
from smolvm.exceptions import (
    SmolVMError,
    CommandExecutionUnavailableError,
    OperationTimeoutError,
)

try:
    with SmolVM() as vm:
        result = vm.run("some-command", timeout=5)
except CommandExecutionUnavailableError as e:
    print(f"SSH not available: {e.reason}")
    print(f"Remediation: {e.remediation}")
except OperationTimeoutError as e:
    print(f"Operation timed out: {e.message}")
except SmolVMError as e:
    print(f"SmolVM error: {e}")
```

## Next steps

<CardGroup cols={2}>
  <Card title="VM lifecycle" icon="circle-play" href="/smolvm/guides/vm-lifecycle">
    Learn about starting, stopping, and managing VM lifecycles
  </Card>

  <Card title="Port forwarding" icon="network-wired" href="/smolvm/features/port-forwarding">
    Expose guest services to your host machine
  </Card>

  <Card title="Environment variables" icon="code" href="/smolvm/guides/environment-variables">
    Inject configuration into your VMs
  </Card>

  <Card title="Custom images" icon="box" href="/smolvm/guides/custom-images">
    Build custom rootfs images for your use case
  </Card>
</CardGroup>
