ol.smolvm
Local microVMs, native execution and Java stream conveniences.
Call initialize before native operations. Operations block until the native call returns. Options and nested configuration maps ignore unrecognized keys. Supplied recognized values must have the documented type. Invalid configuration throws ExceptionInfo with code CONFIG_ERROR. Native failures throw ExceptionInfo with the native code.
Host paths are nonblank strings without NUL characters and are resolved to absolute paths. Guest paths are absolute strings. Machine names and image references are nonblank strings. Resource sizes are positive integers. CPU counts cannot exceed 255, MiB values cannot exceed 4294967295, and GiB values cannot exceed 9223372036854775807. The engine can impose lower platform limits.
A handle returned by create, branch, branch-batch or checkpoint-restore deletes that machine on close. A connect handle does not delete on close. Close children before closing their source. The engine refuses deletion of a source with dependent children. Closing a child never closes its source handle. Explicit delete and repeated close are safe after successful deletion.
initialize
(initialize)
(initialize opts)
Loads the local runtime and returns its version, platform and ABI version.
Call before other operations. Repeated calls are safe but cannot select a different runtime.
| Option | Meaning |
|---|---|
|
Unpacked runtime directory. Defaults to the platform companion JAR. |
check-host
(check-host)
Returns nil when the host supports local machines, otherwise {:code code :reason reason}.
create
(create config)
Creates and starts a machine and returns a Closeable handle.
Closing deletes the machine and its storage, even with :persistent? or :detached?. Use with-open for scoped cleanup. Repeated close, including after delete, is harmless. A failed start deletes the newly created machine. A name conflict does not delete the existing machine.
| Configuration | Meaning |
|---|---|
|
Required machine name. |
|
OCI image reference. Omit for a bare guest. |
|
Positive CPU count. Defaults to the engine setting. |
|
Positive memory limit in MiB. Defaults to the engine setting. |
|
Positive storage size in GiB. Defaults to the engine setting. |
|
Positive overlay size in GiB. Defaults to the engine setting. |
|
Unrestricted outbound networking. Defaults to false. |
|
Vector of CIDR strings for scoped outbound access. Defaults to |
|
Vector of hostname rules for scoped outbound access. Defaults to |
|
|
|
|
|
Enable GPU acceleration. Defaults to false. Requires host support. |
|
Positive GPU shared-memory size in MiB. Defaults to the engine setting. |
|
Forward guest CUDA calls to a host NVIDIA GPU. Defaults to false. Requires host support. |
|
String-to-string environment map. Defaults to |
|
Absolute guest working directory. Defaults to the engine setting. |
|
Nonblank image workload user name or numeric uid[:gid]. Omit for the image default. |
|
Vector of mount maps described below. Defaults to |
|
Vector of TCP mappings |
|
String-to-string label map. Defaults to |
|
Keep the native machine record after the creating process exits. Defaults to true. Does not disable close deletion. |
|
Let the native VM outlive its launching process. Defaults to false. Implies native persistence. Does not disable close deletion. |
|
Start as a live-memory branch source. Defaults to false. Cannot be combined with an interceptor. |
|
Loopback socket address of an existing egress interceptor. Requires |
|
Interceptor credential of 64 hexadecimal digits. Requires |
| Mount key | Meaning |
|---|---|
|
Required host directory string or |
|
Required absolute guest directory. |
|
Boolean, defaults to false. |
|
Boolean, defaults to false. Use a guest-local working copy and copy changes back on |
CIDR or hostname allow lists enable scoped networking without :network? true. The engine validates combinations and platform support. An interceptor is a separately supplied service, not started by this SDK.
connect
(connect name)
(connect name opts)
Connects to an existing machine, starting it if needed.
Returns a borrowed Closeable handle. Closing it does not stop or delete the machine. A frozen branch source can be connected without making it command-ready.
| Option | Meaning |
|---|---|
|
Loopback socket address of an existing interceptor. Supply with |
|
Credential of 64 hexadecimal digits. Supply with |
Omit both interceptor keys to use the engine’s existing binding. The engine validates whether the machine can use the supplied interceptor.
list
(list)
Returns local machine summaries ordered by name.
Each summary includes :name, :state, :image and :labels. Includes machines created by other SDKs and the CLI.
start
(start machine)
(start machine opts)
Starts the machine and waits for guest command execution to become available. Returns machine.
This does not check application listeners or published ports.
| Option | Meaning |
|---|---|
|
Loopback socket address of an existing interceptor. Supply with |
|
Credential of 64 hexadecimal digits. Supply with |
Omit both interceptor keys to use the engine’s existing binding. The engine validates whether the machine can use the supplied interceptor.
exec
(exec machine command)
(exec machine command opts)
Runs a nonempty vector of command strings without inserting a shell.
Returns {:exit-code n :stdout text :stderr text :stdout-bytes bytes :stderr-bytes bytes}. Text uses UTF-8 replacement decoding. Nonzero exit codes do not throw. Buffers all output in memory.
| Option | Meaning |
|---|---|
|
String-to-string environment overrides. Defaults to |
|
Guest working directory. Defaults to the machine setting. |
|
Guest user. Requires an image-backed machine. Defaults to the engine setting. |
|
Positive command timeout. Omit for no caller-specified timeout. Timeout exits with status 124. |
|
Complete UTF-8 text input. Defaults to no input. Not supported with |
|
Token from |
file-write
(file-write machine path data)
(file-write machine path data opts)
Writes a byte array or UTF-8 string to an absolute guest path. Returns nil.
Creates parent directories and replaces existing content.
| Option | Meaning |
|---|---|
|
Unix permission bits, such as |
stream-open
(stream-open machine command)
(stream-open machine command opts)
Starts command and returns a Closeable native stream handle.
Close it even after completion or stream-kill. Unread output accumulates in an unbounded native queue.
| Option | Meaning |
|---|---|
|
String-to-string environment overrides. Defaults to |
|
Guest working directory. Defaults to the machine setting. |
|
Guest user. Requires an image-backed machine. Defaults to the engine setting. |
|
Positive command timeout. Omit for no caller-specified timeout. |
|
Complete UTF-8 text input. Defaults to no input. Not supported on bare guests. |
stream-next
(stream-next stream)
Blocks for one native stream result with no per-read timeout.
Returns {:kind :stdout :data bytes}, {:kind :stderr :data bytes}, {:kind :exit :exit-code n}, or {:kind :error :message text}. Returns nil after completion, cancellation or close.
Use one reader. Another thread may call stream-kill or stream-close. Does not accept a process handle.
cancel-close
(cancel-close token)
Releases a cancellation token without cancelling a running command. Returns nil.
Equivalent to closing the token. Repeated calls are safe.
process
(process machine command)
(process machine command opts)
Starts command and returns a derefable process record.
Dereference to wait for {:exit n :out value :err value}. Nonzero exits are results. Execution, destination-write and cancellation failures throw when dereferenced. Launch errors throw from this call.
:result is a java.util.concurrent.CompletableFuture of the same result map. Use (deref (:result p) timeout-ms timeout-value) for a timed wait. A wait timeout does not cancel the command. Future failures throw ExecutionException. Use ex-cause for the original failure. Ordinary @p throws the original failure directly. Use destroy, not future-cancel, to cancel the guest command.
Consume live output streams while the command runs, or select capture or forwarding. Supplied OutputStreams stay open and unflushed. Native buffering is unbounded. Input streaming is not supported.
| Option | Meaning |
|---|---|
|
|
|
Same choices as |
|
String-to-string environment overrides. Defaults to |
|
Guest working directory. Defaults to the machine setting. |
|
Guest user. Requires an image-backed machine. Defaults to the engine setting. |
|
Positive command timeout. Omit for no caller-specified timeout. |
With :stream, (:out p) and (:err p) expose live java.io.InputStream objects. Close these streams after use. Use destroy for early cancellation. The process record itself is not Closeable.
destroy
(destroy process)
Requests cancellation of a high-level process and returns that handle.
Safe to call from another thread or repeatedly. Does not wait for the guest command to exit. A cancelled process throws with code CANCELLED when dereferenced. Does not accept a native stream handle.
start-branchable
(start-branchable machine)
Starts a created or stopped machine as a live-memory branch source. Returns machine.
Requires state :created or :stopped, otherwise throws INVALID_STATE. Starting an already running machine does not convert it into a branch source.
Use branch or checkpoint after starting it. Requires native branch support. Does not accept interceptor options or check application listeners.
pid
(pid machine)
Returns the native VM process ID, or nil when no process ID is available.
This is a host PID, not the guest PID returned by exec-background.
resume
(resume machine)
Resumes saved machine execution. Returns machine.
Requires resumable saved state. Does not check application listeners.
resize
(resize machine opts)
Resizes a running machine without rebooting and returns its resource totals.
Returns {:cpus n :memory-mib n :storage-gib n-or-nil :overlay-gib n-or-nil}. Sizes are totals, not increments. Supply at least one resource key. The engine checks all targets before applying memory, CPUs and disks in that order. A later failure can leave earlier changes applied.
| Option | Meaning |
|---|---|
|
Positive target CPU count, at most 255. |
|
Positive target memory size, at most 4294967295 MiB. |
|
Positive target storage size, at most 9223372036854775807 GiB. |
|
Positive target overlay size, at most 9223372036854775807 GiB. |
Omitted resources are unchanged. RAM and disks cannot shrink. CPU changes require Linux x86-64 or macOS ARM64. CPU decreases require Linux x86-64 with native offline-CPU support. RAM growth supports Linux x86-64, Linux ARM64 and macOS ARM64, in 128 MiB increments from boot RAM and within runtime capacity. Disk changes fail when the machine has dependent branches. Host headroom and guest capabilities can impose further limits.
branch
(branch machine name)
(branch machine name opts)
Creates a child from a live-memory branch source and returns a Closeable child handle.
name is the new child’s name. The child starts from source memory and disk state. A running source resumes on supported Linux and macOS hosts and stays available for more branches. Machines requiring intercepted egress cannot branch. Native machine and platform restrictions apply.
Closing the child deletes its machine and storage, not the source. Keep the source handle open until all children are closed. A name conflict must not delete an existing machine. No application-port readiness probe runs.
| Option | Meaning |
|---|---|
|
Vector of TCP mappings |
|
Boolean, defaults to false. Make the child suitable for later branches and checkpoints. This requires an eager memory copy instead of the ordinary copy-on-write memory path. |
branch-batch
(branch-batch machine names)
(branch-batch machine names opts)
Creates children from one branch source and returns a vector of Closeable handles in request order.
names is a nonempty vector of distinct machine names. Each child deletes its machine and storage on close. The vector is not Closeable. Close each child before closing the source. Closing a child does not close the source. The native batch removes children it created if the batch fails. Existing machines must not be deleted on a name conflict.
| Option | Meaning |
|---|---|
|
TCP mappings applied to every child, with the same shape as |
|
Positive integer boot width, at most 2147483647. Defaults to 8. |
This operation cannot request branchable children. Use branch with :branchable? true for that case. No application-port readiness probe runs.
checkpoint
(checkpoint machine output)
(checkpoint machine output opts)
Captures a running branchable machine into a host checkpoint artifact.
Returns {:size-bytes n :reused-bytes n :source-pause-ms n :elapsed-ms n}. Byte counts are integers. Durations are milliseconds and can be fractional. output is a host path that must not exist and must end in .checkpoint or .smolcheckpoint (case-insensitive), including when writing a stored checkpoint directory. Capture temporarily pauses the source. The engine checks platform and artifact constraints. Host mounts, staged mounts, remote volumes, GPU and CUDA state are not supported by this capture API. Other host-bound features can also prevent capture.
| Option | Meaning |
|---|---|
|
Host checkpoint-store directory. Omit to write one portable file. With a store, |
Checkpoint files and stores are not deleted when the machine handle closes.
checkpoint-restore
(checkpoint-restore artifact name)
(checkpoint-restore artifact name opts)
Restores a host checkpoint artifact into a new machine and starts it.
artifact is a portable checkpoint file or stored checkpoint directory. name is the new machine name. Returns a Closeable handle. Closing deletes the restored machine and its storage, not the artifact or source machine. A failed start or policy update deletes the newly restored machine. A name conflict must not delete the existing machine.
| Option | Meaning |
|---|---|
|
Boolean, defaults to false. Reuse checkpoint hostname and machine identity. Do not run multiple copies with the same identity. |
|
Policy map accepted by |
|
Loopback address of an existing interceptor for the first start. Requires |
|
Credential of 64 hexadecimal digits. Requires |
Saved-memory restores cannot change network backend. The engine rejects policies incompatible with the saved backend. Restore can fetch referenced images on the host, even with guest networking disabled. Does not check application listeners.
checkpoint-export
(checkpoint-export source output)
Exports a stored checkpoint directory as one portable file and returns its size in bytes.
source and output are host paths. The output must not exist. No filename suffix is required. Does not delete the source checkpoint or its store.
checkpoint-prune
(checkpoint-prune store)
Removes unreferenced objects from a host checkpoint store and returns the bytes freed.
store is a host directory. This deletes stored objects that no checkpoint in the store references.
egress-policy-set
(egress-policy-set machine policy)
Replaces a created or stopped machine’s outbound network policy. Returns machine.
Saved-memory machines keep their network backend. A policy requiring a different backend fails.
| Policy key | Meaning |
|---|---|
|
Required boolean. True permits unrestricted outbound access. False blocks it except for supplied allow lists. |
|
Vector of CIDR strings. Defaults to |
|
Vector of hostname rules. Defaults to |
{:network? false} with empty allow lists denies outbound access. No interceptor service is created.
host-port
(host-port machine guest-port)
Returns the host port forwarding to guest-port, or nil if no mapping is available.
guest-port is an integer from 0 through 65535. This lookup does not check whether an application is accepting connections.
guest-ports
(guest-ports machine)
Returns a vector of guest ports reported by the native machine.
This lists configured forwarding targets, not listening guest sockets.
published-ports
(published-ports machine)
Returns a vector of published mappings {:host n :guest n :protocol protocol}.
Protocol is :tcp or :udp.
Reads the persisted machine record even when stopped. Does not probe listeners.
ports-set
(ports-set machine ports)
Replaces all published port mappings. Returns machine.
ports is a vector of at most 64 maps. An empty vector removes all mappings. Running machines can update TCP mappings through the native ports control socket when available. UDP changes require a stopped machine. A missing or incompatible control socket causes a native failure.
| Mapping key | Meaning |
|---|---|
|
Required integer from 0 through 65535. Zero selects a free host port. |
|
Required integer from 0 through 65535. The engine validates usable ports. |
|
|
Read published-ports for the effective mappings. No listener readiness probe runs.
exec-background
(exec-background machine command)
(exec-background machine command opts)
Starts a nonempty command vector without a shell and returns its guest PID.
Does not wait for exit or collect output. This PID is not a Closeable process handle. The SDK provides no background wait or cancellation handle.
| Option | Meaning |
|---|---|
|
String-to-string environment overrides. Defaults to |
|
Absolute guest working directory. Defaults to the machine setting. |
|
Nonblank guest user. Requires an image-backed machine. Defaults to the engine setting. |
|
Unsupported. Supplying this key throws CONFIG_ERROR. |
|
Unsupported. Supplying this key throws CONFIG_ERROR. |
|
Unsupported. Supplying this key throws CONFIG_ERROR. |
run
(run machine image command)
(run machine image command opts)
Pulls an OCI image if needed and runs a command in a container of that image.
command is a nonempty vector of strings. Returns the same result map as exec, with UTF-8 text and byte-array output. Buffers all output. Nonzero exits do not throw. Pulling an uncached image uses the network.
| Option | Meaning |
|---|---|
|
String-to-string environment overrides. Defaults to |
|
Absolute container working directory. Defaults to the engine setting. |
|
Positive timeout, at most 9223372036854775807 milliseconds. Omit for no caller-specified timeout. Timeout exits with status 124. |
|
Unsupported. Supplying this key throws CONFIG_ERROR. Use an image-backed machine and |
|
Unsupported. Supplying this key throws CONFIG_ERROR. |
|
Unsupported. Supplying this key throws CONFIG_ERROR. |
image-pull
(image-pull machine image)
Pulls an OCI image into machine storage and returns its metadata.
Returns {:reference text :digest text :size n :architecture text :os text}. Size is bytes. Pulling can access the network.
image-list
(image-list machine)
Returns a vector of cached OCI image metadata maps.
Each map has the same fields as image-pull.
pack
(pack machine output)
Packs a stopped machine into a host artifact and returns the resulting .smolmachine path string.
output is the destination host path. The engine adds the .smolmachine suffix if needed and writes a runnable file beside the artifact. It uses the CLI bundled with the native runtime. The artifact is not deleted when the handle closes.
sync
(sync machine)
Copies staged mount changes back to their host directories without stopping the machine.
Returns machine. This can change host files. It is not a general disk flush operation.
machine-name
(machine-name machine)
Returns the machine handle’s name string without a native call.
Local machine IDs are the same as names. This does not check whether the machine still exists.
ready?
(ready? machine)
Returns whether the machine is running and its published guest ports pass a TCP readiness probe.
Returns false for a non-running machine, a missing host mapping or a failed probe. A running machine with no guest ports returns true. Native state and mapping errors propagate.
Each probe connects to 127.0.0.1 with a 250 millisecond connect timeout, then reads at most one byte with a 100 millisecond read timeout. A byte received or a read timeout counts as ready. EOF, reset or connection failure counts as not ready. Each probe socket is closed.
This matches the Go local heuristic, not application health. It can consume a greeting byte and create service logs. It cannot establish UDP readiness. No application request is sent.
wait-until-ready
(wait-until-ready machine)
(wait-until-ready machine opts)
Polls ready? and returns machine when the probe succeeds.
Probes immediately, then sleeps between attempts. Native errors propagate. Non-running states keep polling rather than failing immediately. If another full interval would exceed the deadline, throws TIMEOUT. The deadline does not interrupt an active native call or probe. A successful active probe can finish after the deadline. Thread interruption stops the wait without stopping or deleting the machine.
| Option | Meaning |
|---|---|
|
Positive integer milliseconds, at most 9223372036854775807. Defaults to 120000. |
|
Positive integer milliseconds, at most 9223372036854775807. Defaults to 1000. |
This is a machine readiness helper, not a process result waiter. Existing create, connect, start, resume and branch functions do not call it automatically.
endpoint
(endpoint machine guest-port)
(endpoint machine guest-port path)
Returns local HTTP and WebSocket URLs for a published guest port.
Returns {:http-url text :ws-url text :headers {}} using 127.0.0.1 and the current host mapping. guest-port is an integer from 1 through 65535. An absent mapping throws CONFIG_ERROR. This reads the mapping but does not probe or publish a port.
path is a string, defaults to empty, and must contain URI-valid text. An empty path adds no suffix. Otherwise all leading slashes are replaced by one slash. Queries and fragments are preserved. Supply percent escapes where needed. The host and scheme cannot be replaced by the path.
http-request
(http-request machine guest-port path)
(http-request machine guest-port path opts)
Builds a babashka.http-client request map for a local machine’s guest port without sending it.
guest-port and path follow endpoint. Reads the current native mapping, so construction is not a pure function. The returned map is request data only.
Returns {:method method :uri text :headers headers :body body}. Send it with babashka.http-client/request, adding that client’s response and transport options as needed. Building the map neither reads nor closes the body.
| Option | Meaning |
|---|---|
|
|
|
String-to-string map. Defaults to |
|
String, byte array, |
fetch
(fetch machine guest-port path)
(fetch machine guest-port path opts)
Sends an HTTP GET to a published local guest port and returns a response map.
guest-port and path follow endpoint. Blocks until response headers are available. Returns at least {:status integer :headers map :body input-stream}. Close the response body, including for non-success status codes. HTTP error statuses do not throw. Transport failures and native mapping errors propagate.
Follows HTTP and HTTPS redirects, including HTTPS to HTTP, through the HTTP client’s built-in redirect support. Redirects can leave the local machine. Redirect limits and header forwarding follow the Java HTTP client, not Go’s exact redirect policy. No custom redirect loop or application-level retry runs. No readiness wait runs. The default has no request timeout. A timeout limits receipt of response headers, not later reads from the body stream.
| Option | Meaning |
|---|---|
|
String-to-string request headers, as in |
|
Positive integer milliseconds, at most 9223372036854775807. Omit for no request timeout. |
Uses the existing babashka.http-client dependency. Use http-request and that client directly for other methods or response formats.
publish
(publish machine opts)
Adds or replaces one published mapping and returns its effective map.
Returns {:host integer :guest integer :protocol keyword}. Replaces mappings with the same host port and protocol, preserving other mappings. If host is zero, briefly binds a loopback socket of the selected protocol to choose a free port, then closes it before publishing. Another process can take that port before publication. Native failures propagate without retry.
Reads mappings, applies ports-set, then reads them again. This is not an atomic update. Serialize port changes for the same machine, including changes from other handles or processes. A readback failure can occur after the update took effect. Returns the exact new mapping if present, otherwise another mapping for the same guest and protocol. If neither appears, throws INVALID_STATE rather than reporting unverified success.
| Option | Meaning |
|---|---|
|
Required guest port integer from 1 through 65535. |
|
Host port integer from 0 through 65535. Defaults to 0, selecting a free port. |
|
|
Running TCP changes require the native ports control socket. UDP changes require a stopped machine. No readiness probe runs.
unpublish
(unpublish machine opts)
Removes matching published mappings and returns machine.
Matches all supplied selectors and the protocol. Omitting a selector matches every value for it. At least one selector is required. A match-free call makes no update. This does not explicitly close established connections.
| Option | Meaning |
|---|---|
|
Guest port integer from 1 through 65535. Omit to match every guest port. |
|
Host port integer from 1 through 65535. Omit to match every host port. |
|
|
Reads current mappings and replaces the filtered list through ports-set. This is not atomic. Serialize concurrent port changes. Running TCP changes require a compatible control socket. UDP changes require a stopped machine.
file-read-stream
(file-read-stream machine path)
Reads an absolute guest file path and returns a java.io.InputStream over its bytes.
Reads and buffers the entire file before returning. This is not a bounded-memory or incremental native read. An empty file returns a stream at EOF. Native read errors occur during this call, not on later stream reads. Close the returned stream after use.
branch-exec
(branch-exec machine name command)
(branch-exec machine name command opts)
Branches a temporary child, runs one command in it, then deletes the child.
name is a nonblank unused child name. command and opts have the same contract and option table as exec. Returns its result map, including nonzero exit codes without throwing. No additional branch options are accepted. The source must support branch.
Deletes only a child successfully created by this call, on success or failure. A name conflict must not delete an existing machine. Cleanup failure after successful execution throws. If execution and cleanup both fail, preserves the execution failure and attaches the cleanup failure as a suppressed exception. Does not stop or delete the source. A native branch can briefly pause it. No application readiness wait runs.
| Option | Meaning |
|---|---|
|
String-to-string environment overrides. Defaults to |
|
Guest working directory. Defaults to the machine setting. |
|
Guest user. Requires an image-backed machine. Defaults to the engine setting. |
|
Positive command timeout. Omit for no caller-specified timeout. Timeout exits with status 124. |
|
Complete UTF-8 text input. Defaults to no input. Not supported with |
|
Token from |