Rust SDK

The Rust SDK runs microVMs from a Rust program, locally or on smol cloud, through the same Machine API the Node and Python SDKs expose. On the local target the crate drives a smolvm engine as a child process, fetching one on its own if the host has none.

Install

The crate is named smolmachines.

cargo add smolmachines

The local target does not need the CLI installed. crates.io serves source rather than binaries, so on the first call that asks for a local machine the crate downloads the engine release matching its own version and caches it; nothing is downloaded for a cloud machine. Point SMOLVM at a binary to use an installed engine instead, SMOLMACHINES_CACHE_DIR to move the cache, SMOLMACHINES_ENGINE_VERSION to pin a different engine, and SMOLMACHINES_NO_DOWNLOAD=1 to refuse the fetch, which makes a host with no engine fail rather than reach the network. The cloud target needs none of this.

For the local target, the supported hosts are macOS on Apple Silicon and Linux x64 or arm64 with glibc 2.34 or newer, each with a hypervisor: the Hypervisor framework on macOS, KVM on Linux. The cloud target works anywhere the crate builds.

Create a local machine

use smolmachines::Machine;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let machine = Machine::builder("hello")
        .image("alpine:latest")
        .cpus(1)
        .memory_mib(512)
        .network(true)
        .create()?;

    machine.start()?;
    let result = machine.exec(["uname", "-sm"])?;
    println!("{}", result.stdout_utf8().trim());
    machine.delete()?;
    Ok(())
}

The builder takes the machine’s name, and create() returns before the machine is started, so start() is a separate call. exec returns a result whose stdout_utf8() is the captured output.

Networking is off unless you ask for it. On the local target the crate drives the engine of its own version, which fetches an uncached registry image on the host whenever the machine cannot reach the registry itself, so .network(true) is for the workload rather than the image. Pin a different engine with SMOLMACHINES_ENGINE_VERSION.

update_network(&policy) replaces a stopped local machine’s network policy with exactly the one given (no network, every host, or an allow list that drops whatever the machine allowed before), from its next start, and network() reads the policy back. A cloud machine’s network is set when it is created. smolmachines::engine_cli() returns the path of the engine binary the crate drives, for a program that runs smolvm machine exec -t in its own terminal while the SDK manages the machine.

Choose local or cloud

The default is local. Only an explicit credential moves that, either api_key on ConnectOptions or SMOL_CLOUD_TOKEN in the environment, so a smol auth login session on disk never silently redirects a program that meant to run locally.

use smolmachines::{ConnectOptions, Machine};

// Local: the engine runs in this process.
let local = Machine::builder("here").image("alpine:latest").create()?;

// Cloud: the control plane runs it. create_with also starts the machine and
// waits for its agent, so it is ready to work when this returns.
let remote = Machine::builder("there")
    .image("alpine:latest")
    .auto_stop_seconds(300)
    .create_with(&ConnectOptions::cloud())?;

create_with on the cloud target starts the machine and waits for its agent, so unlike the local path it does not need a separate start().

Which SDK to reach for

You are writingPackagePage
Rustsmolmachines on crates.iothis page
TypeScript or JavaScriptsmolmachines on npmSDK Quick Start
Pythonsmolmachines on PyPISDK Quick Start
Gogithub.com/smol-machines/smol/sdk/goSDK Quick Start

All four drive the same engine and the same cloud API. The Node and Python packages embed it through NAPI and pyo3, and the Go module loads it without cgo; the Rust crate drives the engine as a child process and fetches it when the host has none.

See Machine API for the method surface the three share, and Use SDK on Cloud for the cloud target’s configuration fields.