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 writing | Package | Page |
|---|---|---|
| Rust | smolmachines on crates.io | this page |
| TypeScript or JavaScript | smolmachines on npm | SDK Quick Start |
| Python | smolmachines on PyPI | SDK Quick Start |
| Go | github.com/smol-machines/smol/sdk/go | SDK 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.