Skip to main content
General

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?

LibraryHosted
RunsInside your processDurable instance on Rivet Cloud or self-hosted
LifecycleRuns until dispose() or process exitSleeps when idle unless a process is running
ClientsYour backendYour backend, or browsers with a scoped JWT
Preview URLsNoneExpiring preview URLs

Create a VM

Install the library

npm install @rivet-dev/agentos-core

Create a VM and use it

import { AgentOs } from "@rivet-dev/agentos-core";

// Boots a VM inside this process. It runs until dispose() or process exit.
const vm = await AgentOs.create();

try {
	// Bash
	const result = await vm.process.exec("echo hello && ls /home/agentos", {
		output: { capture: "all" },
	});
	console.log(result.stdout);

	// Filesystem
	await vm.filesystem.writeFile("/home/agentos/hello.txt", "Hello, world!");
	const file = await vm.filesystem.readFile("/home/agentos/hello.txt");
	console.log(new TextDecoder().decode(file));

	// JavaScript
	await vm.javascript.execute("console.log(1 + 2)");

	// Python
	const answer = await vm.python.evaluate<number>("21 * 2");
	console.log(answer.outcome === "succeeded" ? answer.value : answer.error);
} finally {
	await vm.dispose();
}

The VM runs until dispose() is called or your process exits.

Configure the VM

The filesystem is in memory by default. Pass options to AgentOs.create() to persist it, attach other filesystems, and lock the VM down.

import { resolve } from "node:path";
import { AgentOs } from "@rivet-dev/agentos-core";

const vm = await AgentOs.create({
	// Store the root filesystem in SQLite so files survive VM recreation.
	database: { type: "sqlite_file", path: resolve("agentos.sqlite") },
	rootFilesystem: { type: "native", plugin: { id: "chunked_sqlite", config: {} } },

	// Attach a host directory (read-only) and an S3 bucket.
	mounts: [
		{
			path: "/mnt/code",
			plugin: { id: "host_dir", config: { hostPath: "/path/to/repo" } },
			readOnly: true,
		},
		{
			path: "/mnt/data",
			plugin: { id: "chunked_s3", config: { bucket: "my-bucket", region: "us-east-1" } },
		},
	],

	// Environment variables for guest processes.
	environment: { NODE_ENV: "production" },

	// Deny network access except to one host.
	permissions: {
		network: {
			default: "deny",
			rules: [
				{
					mode: "allow",
					operations: ["*"],
					patterns: ["dns://api.example.com", "tcp://api.example.com:*"],
				},
			],
		},
	},

	// Cap processes and filesystem size.
	limits: { resources: { maxProcesses: 64, maxFilesystemBytes: 256 * 1024 * 1024 } },
});

await vm.dispose();

See Filesystem, Persistence, Permissions, and Resource Limits.

Next steps