Quick start

This guide assumes a3s-box --version and a3s-box info succeed. Follow the installation guide first if the runtime is not installed.

Inspect host capabilities

a3s-box info

The output identifies the host architecture, virtualization backend, supported guest channel, and runtime paths. A workload is admitted only when the host can enforce the requested configuration.

Run one command in a MicroVM

Omitting --isolation selects the default dedicated-kernel path:

a3s-box run --rm alpine:3.20 -- \
  sh -lc 'echo "inside $(uname -s)"; uname -r'

Box pulls the OCI image if required, prepares a root filesystem, starts the MicroVM, propagates the workload exit code, and removes the terminal box.

Manage a long-running service

a3s-box run -d \
  --name web \
  --memory 1g \
  -p 8080:80 \
  nginx:alpine

a3s-box ps
a3s-box inspect web
a3s-box logs -f web
a3s-box exec web -- nginx -v
a3s-box stats web --no-stream
a3s-box stop web
a3s-box rm web

Names are convenient queries; the runtime internally uses stable box IDs and generation fencing to reject stale lifecycle operations.

Persist data

Create and attach a named volume:

a3s-box volume create app-data

a3s-box run --rm \
  --mount type=volume,source=app-data,target=/data \
  alpine:3.20 -- \
  sh -lc 'date -u > /data/created-at'

a3s-box volume inspect app-data

See storage and snapshots for bind mounts, tmpfs, commits, exports, and filesystem snapshots.

Select the shared-kernel Sandbox

On a certified Linux host, request the Sandbox explicitly:

a3s-box run --rm \
  --isolation sandbox \
  --cpus 2 \
  --memory 512m \
  alpine:3.20 -- \
  sh -lc 'id; cat /proc/self/status'

An explicit --isolation microvm value is rejected. Omission is the public way to select the default, which prevents scripts from treating backend names as interchangeable compatibility modes.

Use a native SDK

Each SDK example below is a complete program that creates a Sandbox, runs one guest command, prints the result, and cleans up.

Rust
Go
Python
TypeScript
use a3s_box_sdk::Sandbox;

#[tokio::main]
async fn main() -> Result<(), a3s_box_sdk::ClientError> {
    let sandbox = Sandbox::create("alpine:3.20").await?;
    let result = sandbox.commands.run("printf ready").await?;

    println!("{}", result.stdout);
    sandbox.kill().await?;
    Ok(())
}

TypeScript lifecycle

Scroll or select a step. The panel on the right shows the matching code and highlights the current operation.

RUN STEPSCreate a MicroVM
sandbox.tsTYPESCRIPT
import { Sandbox } from '@a3s-lab/box';
async function main(): Promise<void> {
const sandbox = await Sandbox.create('alpine:3.20');
await sandbox.kill();
}
main().catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});
RUN STEPSSet resources and networking
sandbox.tsTYPESCRIPT
import { Sandbox } from '@a3s-lab/box';
async function main(): Promise<void> {
const sandbox = await Sandbox.create('alpine:3.20', {
cpus: 2,
memoryMb: 1024,
network: { mode: 'none' },
});
await sandbox.kill();
}
main().catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});
RUN STEPSWrite a workspace file
sandbox.tsTYPESCRIPT
import { Sandbox } from '@a3s-lab/box';
async function main(): Promise<void> {
const sandbox = await Sandbox.create('alpine:3.20', {
cpus: 2,
memoryMb: 1024,
network: { mode: 'none' },
});
try {
await sandbox.files.write('/workspace/status.txt', 'ready\n');
console.log(await sandbox.files.read('/workspace/status.txt'));
} finally {
await sandbox.kill();
}
}
main().catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});
RUN STEPSRun a command and check the result
sandbox.tsTYPESCRIPT
import { Sandbox } from '@a3s-lab/box';
async function main(): Promise<void> {
const sandbox = await Sandbox.create('alpine:3.20', {
cpus: 2,
memoryMb: 1024,
network: { mode: 'none' },
});
try {
await sandbox.files.write('/workspace/status.txt', 'ready\n');
const result = await sandbox.commands.run(
['test', '-s', '/workspace/status.txt'],
{ timeoutMs: 30_000 },
);
if (result.exitCode !== 0) {
throw new Error(result.stderr);
}
console.log(result.stdout);
} finally {
await sandbox.kill();
}
}
main().catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});
RUN STEPSAlways clean up the Sandbox
sandbox.tsTYPESCRIPT
import { Sandbox } from '@a3s-lab/box';
async function main(): Promise<void> {
const sandbox = await Sandbox.create('alpine:3.20', {
cpus: 2,
memoryMb: 1024,
network: { mode: 'none' },
});
try {
await sandbox.files.write('/workspace/status.txt', 'ready\n');
const result = await sandbox.commands.run(
['test', '-s', '/workspace/status.txt'],
{ timeoutMs: 30_000 },
);
if (result.exitCode !== 0) {
throw new Error(result.stderr);
}
console.log(result.stdout);
} finally {
await sandbox.kill();
}
}
main().catch((error: unknown) => {
console.error(error);
process.exitCode = 1;
});

The SDK overview explains the shared contract and links to language-specific guides.

Platform notes

  • Linux/KVM supports the broadest runtime surface.
  • macOS requires Apple Silicon and uses HVF.
  • Windows x86_64 uses WHPX and has explicit limitations for bridge networking, post-boot exec, memory snapshots, TEE, Compose workloads, and CRI.

Review the platform matrix and the Windows guide before relying on a platform-specific feature.

Next step

Continue with Architecture and isolation to understand how the workload you just ran passes admission, selects an isolation boundary, and persists lifecycle state. Then move on to Images and builds.