VMs
A VM is a full Linux computer with a graphical screen. Watch and control it right in your browser, or drive it from the SDK to automate anything a person could do on screen.
Create one
Start a VM from the console under VMs → New, or from the SDK. It's ready almost instantly, usually in about a second.
npm install @solarisdk/desktopimport { DesktopClient } from "@solarisdk/desktop"
const desktops = new DesktopClient({
apiKey: process.env.SOLARI_API_KEY!, // your Solari API key
baseUrl: "https://api.getsolari.com",
})
// Starts in about a second.
const desktop = await desktops.create({
template: "default",
resolution: "1280x720",
cpu: 4, // number of CPUs, 1-16 (default 2)
memMb: 8192, // memory in MB, up to 65536 (default 2048)
timeoutMs: 15 * 60 * 1000, // pause after 15 min of no activity
lifecycle: { onTimeout: "pause" }, // when idle: pause (resumable), or "kill"
})
console.log("watch it live:", desktop.streamUrl)Choose its size
When you create a VM you can pick how many CPUs it has (from 1 to 16, default 2) and how much memory (from 2 GB up to 64 GB, default 2 GB). Set cpu and memMb at create time. The size sticks: if you pause the VM and come back later, it resumes at the same size, so you don't need to set it again.
// A bigger VM for a heavier workload.
const big = await desktops.create({
template: "default",
cpu: 8,
memMb: 16384,
})cpu/memMb on resume.Drive it
connect() opens the connection so you can control the VM. From there you have the full toolkit: mouse and keyboard, screenshots, a shell, files, the clipboard, running processes, and launching apps. Wait for health() before your first action so the screen is up and ready.
await desktop.connect()
const health = await desktop.health() // { ready, display, vnc }
if (!health.ready) throw new Error("VM not ready")Mouse & keyboard
The VM responds to real mouse and keyboard input. Pass humanize: true for a natural, curved mouse path instead of an instant jump. This helps on sites that watch how the pointer moves.
// Mouse: move, click, press-drag, scroll.
await desktop.mouse.move(640, 360, { humanize: true })
await desktop.mouse.click(640, 360, { button: "left", humanize: true })
await desktop.mouse.down(640, 360, "left")
await desktop.mouse.move(720, 360, { humanize: true })
await desktop.mouse.up(720, 360, "left") // drag
await desktop.mouse.scroll(640, 360, { humanize: true })
// Keyboard: type text, or press key combinations.
await desktop.keyboard.type("hello world")
await desktop.keyboard.press(["ctrl", "s"]) // chord
await desktop.keyboard.down(["shift"])
await desktop.keyboard.up(["shift"])Screenshots
screenshot() returns an image of the screen as a Uint8Array. PNG by default, or JPEG with a quality setting for smaller images when you capture in a loop.
const png = await desktop.screenshot({ format: "png" })
const jpg = await desktop.screenshot({ format: "jpeg", quality: 70 })Shell & files
exec runs a command and waits for it to finish; pass an onChunk callback to stream the output as it arrives. The fs tools read and write files directly.
// One-shot command.
const { exitCode, stdout, stderr } = await desktop.exec("uname", {
args: ["-a"],
})
// Streamed command.
await desktop.execStream("apt-get",
({ stream, text }) => process.stdout.write(text),
{ args: ["install", "-y", "jq"] })
// Files: read, write, list.
await desktop.fs.write("/tmp/note.txt", "hello")
const text = await desktop.fs.readText("/tmp/note.txt")
const entries = await desktop.fs.list("/home")Clipboard, apps & processes
// Copy and paste between your app and the VM.
await desktop.clipboard.set("paste me")
const clip = await desktop.clipboard.get()
// Launch an app by name; returns its pid.
const pid = await desktop.open("firefox", ["https://example.com"])
// Inspect and manage the process table.
const procs = await desktop.process.list()
await desktop.process.kill(pid)
// Resize the display on the fly.
await desktop.display.set(1920, 1080)Watch it live
Every VM comes with a live view you can watch and control. streamUrl is ready when you create the VM; open it in a viewer (the console does this for you in the in-browser View tab) to watch and take over interactively.
const { streamUrl } = await desktop.stream.start()
// Open streamUrl in a viewer to watch and control the VM.Re-attach later
Every VM has a stable id. connect(id) reconnects to a VM you started earlier, and resumes it if it was paused.
const box = await desktops.connect("dsk_abc123")
await box.connect()
await box.exec("whoami")Idle timeout
A VM stays running as long as you're using it. Set timeoutMs at create time to say how long it can sit idle; every action and every open connection resets the clock. When that time passes with no activity, lifecycle decides what happens: onTimeout: "pause" (the default) parks the VM and its state is saved, so the next connect() picks up right where you left off, while onTimeout: "kill" shuts it down. If you don't set timeoutMs, it defaults to 30 minutes.
// Change how long it can sit idle (ms).
await desktop.setTimeout(15 * 60 * 1000)
// Pause it now: state is saved, resumes on the next connect().
await desktop.pause()Tear down
close() ends your connection; destroy(id) shuts the VM down for good. It can't be recovered.
desktop.close()
await desktops.destroy(desktop.sessionId)@solarisdk/sandbox package. Same idea and same lifecycle, just SandboxClient instead of DesktopClient. Want both from one client plus the solari CLI? Install @solarisdk/sdk and use solari.desktops / solari.sandboxes.