Skip to content

Machine โ€‹

A machine is a microVM instance that provides an isolated execution environment.

Creating a Machine โ€‹

typescript
import { Machine } from 'smolvm';

// Basic creation
const machine = await Machine.create({ name: 'my-machine' });

// With configuration
const machine = await Machine.create({
  name: 'configured-machine',
  mounts: [
    { source: '/host/code', target: '/workspace' }
  ],
  resources: {
    cpus: 2,
    memoryMb: 1024
  }
});
python
from smolvm import Machine, MachineConfig, MountSpec, ResourceSpec

# Basic creation
machine = await Machine.create(MachineConfig(name="my-machine"))

# With configuration
config = MachineConfig(
    name="configured-machine",
    mounts=[
        MountSpec(source="/host/code", target="/workspace")
    ],
    resources=ResourceSpec(
        cpus=2,
        memory_mb=1024
    )
)
machine = await Machine.create(config)

Configuration Options โ€‹

OptionTypeDefaultDescription
namestringrequiredUnique machine identifier
serverUrlstringhttp://127.0.0.1:8080Server URL
mountsMountSpec[][]Volume mounts
portsPortSpec[][]Port forwarding
resourcesResourceSpecdefaultCPU and memory limits

Lifecycle Methods โ€‹

start() โ€‹

Creates and starts the machine. Called automatically by Machine.create().

typescript
const machine = new Machine({ name: 'manual' });
await machine.start();
python
machine = Machine(MachineConfig(name="manual"))
await machine.start()

stop() โ€‹

Stops the machine. The machine can be restarted.

typescript
await machine.stop();
python
await machine.stop()

delete() โ€‹

Deletes the machine. This is permanent.

typescript
await machine.delete();
python
await machine.delete()

status() โ€‹

Gets the current machine status.

typescript
const info = await machine.status();
console.log(info.state); // 'running', 'stopped', etc.
python
info = await machine.status()
print(info.state)  # 'running', 'stopped', etc.

Execution Methods โ€‹

exec() โ€‹

Execute a command directly in the microVM.

typescript
const result = await machine.exec(['ls', '-la', '/']);

// With options
const result = await machine.exec(['long-running-task'], {
  timeout: 60000, // 60 seconds
  env: { MY_VAR: 'value' },
  workdir: '/tmp'
});
python
result = await machine.exec(["ls", "-la", "/"])

# With options
result = await machine.exec(
    ["long-running-task"],
    timeout=60.0,  # 60 seconds
    env={"MY_VAR": "value"},
    workdir="/tmp"
)

run() โ€‹

Run a command in a container image.

typescript
const result = await machine.run(
  'python:3.12-alpine',
  ['python', '-c', 'print("Hello")']
);

// With options
const result = await machine.run(
  'node:22-alpine',
  ['node', 'script.js'],
  {
    timeout: 30000,
    env: { NODE_ENV: 'production' }
  }
);
python
result = await machine.run(
    "python:3.12-alpine",
    ["python", "-c", "print('Hello')"]
)

# With options
result = await machine.run(
    "node:22-alpine",
    ["node", "script.js"],
    timeout=30.0,
    env={"NODE_ENV": "production"}
)

Best Practices โ€‹

Use Context Managers (Python) โ€‹

Python's async context manager ensures cleanup:

python
async with Machine(config) as machine:
    await machine.start()
    # ... use machine
# Automatically stops, deletes, and closes

Use withMachine (TypeScript) โ€‹

The helper function ensures cleanup:

typescript
const result = await withMachine(config, async (machine) => {
  return machine.exec(['whoami']);
});
// Automatically stops and deletes

Reuse Machinees โ€‹

For multiple commands, reuse the same machine:

typescript
// Good - one machine, multiple commands
const machine = await Machine.create({ name: 'worker' });
for (const task of tasks) {
  await machine.exec(task.command);
}
await machine.stop();

// Bad - new machine per command (slow)
for (const task of tasks) {
  await quickExec(task.command); // Creates new machine each time
}