Quickstart (Library)
Run agentOS VMs directly inside a Node.js application with @rivet-dev/agentos-core.
Use agentOS as a library to run VMs inside your own Node.js process. To create durable VMs by ID and control them over HTTP instead, see the hosted quickstart.
Which one should I use?
| Hosted | Library | |
|---|---|---|
| Runs | As a durable instance on Rivet Cloud or a self-hosted Docker image | Embedded inside your process as a library |
| Lifecycle | Durable, sleeps when idle unless a process is running; see actor lifecycle | Ephemeral, runs until dispose() or process exit |
| Package | @rivet-dev/agentos, or plain HTTP | @rivet-dev/agentos-core |
| VM identity | A durable VM you create by key and reach by ID | A handle your process owns until dispose() |
| Configuration | Stored with the VM and versioned | Passed to AgentOs.create() |
| Clients | Your backend, or browsers with a scoped JWT | Your backend |
| Host access | None | Host functions, host mounts, external sandboxes |
| Previews | Expiring preview URLs | None |
| Best for | Long-lived VMs shared across clients | Embedding VMs in an existing backend |
Create a VM
Install the library
npm install @rivet-dev/agentos-core
Create a VM
import { AgentOs } from "@rivet-dev/agentos-core";
// `AgentOs.create()` boots a VM inside this process and returns a handle to it.
const vm = await AgentOs.create();
The VM runs until dispose() is called or your process exits.
Show me the code
Run Bash Commands
const result = await vm.process.exec("echo hello && ls /home/agentos", {
output: { capture: "all" },
});
console.log(result.stdout);
Work With the Filesystem
await vm.filesystem.writeFile("/home/agentos/hello.txt", "Hello, world!");
const file = await vm.filesystem.readFile("/home/agentos/hello.txt");
Run a Dev Server
Start a Node.js server in the VM, then send it a request from your process. The listener is not exposed on the host network.
await vm.filesystem.writeFile(
"/home/agentos/server.js",
`require("node:http")
.createServer((req, res) => res.end("hello"))
.listen(3000);`,
);
await vm.process.spawn("node", ["/home/agentos/server.js"]);
// The listener stays inside the VM. Send it a request from the host.
const response = await vm.network.httpRequest({ port: 3000, path: "/" });
console.log(new TextDecoder().decode(response.body));
Use the Language Runtimes
Run JavaScript, TypeScript, and Python directly, with npm and pip installs built in.
await vm.javascript.execute("console.log(1 + 2)");
await vm.typescript.execute("const n: number = 3; console.log(n)");
const answer = await vm.python.evaluate<number>("21 * 2");
Schedule Cron Jobs
vm.cron.schedule({
id: "cleanup",
schedule: "0 * * * *",
action: { type: "exec", command: "rm", args: ["-rf", "/tmp/cache"] },
});
Install Software
Install tools from the software registry
while the VM is running. Packages are verified against their digest before
their commands appear on /opt/agentos/bin.
// Registry packages are published next to a manifest with each release.
const base = "https://releases.rivet.dev/agent-os/latest/software/";
const manifest = (await (await fetch(`${base}manifest.json`)).json()) as {
artifacts: { name: string; digest: string; path: string }[];
};
const ripgrep = manifest.artifacts.find((artifact) => artifact.name === "ripgrep");
if (!ripgrep) throw new Error("ripgrep is not in the manifest");
await vm.software.install({
type: "url",
url: new URL(ripgrep.path, base).href,
expectedDigest: ripgrep.digest,
});
Persist Files
The filesystem is in memory by default. Store the root filesystem in SQLite to keep files across VM recreation.
import { mkdirSync } from "node:fs";
import { resolve } from "node:path";
import { AgentOs, type AgentOsOptions } from "@rivet-dev/agentos-core";
mkdirSync(".agentos", { recursive: true });
const options = {
// The SQLite file that stores the VM's durable state.
database: {
type: "sqlite_file",
path: resolve(".agentos/agentos.sqlite"),
},
// Store the root filesystem in that database instead of in memory.
rootFilesystem: {
type: "native",
plugin: { id: "chunked_sqlite", config: {} },
},
} satisfies AgentOsOptions;
let vm = await AgentOs.create(options);
await vm.filesystem.writeFile("/home/agentos/result.txt", "persistent");
await vm.dispose();
vm = await AgentOs.create(options);
const result = await vm.filesystem.readFile("/home/agentos/result.txt");
console.log(new TextDecoder().decode(result));
await vm.dispose();
Next steps
- Expose your own functions to guest code with host functions.
- Lock the VM down with Permissions and Resource Limits.