TypeScript SDK
The official TypeScript clients for the three Solari products: browsers (a connected Playwright Browser in the cloud), VMs (GUI desktops you drive with mouse, keyboard, and screenshots), and sandboxes (headless microVMs for commands, code, and files). Each product ships as its own package; install only what you use, or take @solarisdk/sdk for all three.
Installation
| Package | Product | Classes |
|---|---|---|
@solarisdk/browser | Cloud browsers | Solari, BrowserSession |
@solarisdk/desktop | VMs (GUI desktops) | DesktopClient, Desktop |
@solarisdk/sandbox | Sandboxes (headless) | SandboxClient, Sandbox |
@solarisdk/sdk | All three (unified) | SolariClient + the solari CLI |
npm install @solarisdk/browser # browsers
npm install @solarisdk/desktop # VMs
npm install @solarisdk/sandbox # sandboxes
npm install @solarisdk/sdk # all three + the solari CLIESM only
Every package is
type: "module" and exposes only an import condition. There is no CommonJS build. @solarisdk/browser needs Node >=20; the others need >=18. await using needs Node 22+.Getting Started
Launch a browser
import { Solari } from "@solarisdk/browser";
const solari = new Solari({ apiKey: process.env.SOLARI_API_KEY! });
const browser = await solari.launch({ stealth: true, proxy: "us" });
const page = await browser.newPage();
await page.goto("https://example.com");
console.log(await page.title());
await browser.close(); // closes the browser AND releases the sessionCreate a VM
import { DesktopClient } from "@solarisdk/desktop";
const client = new DesktopClient({
apiKey: process.env.SOLARI_API_KEY!,
baseUrl: "https://api.getsolari.com",
});
const vm = await client.create({ template: "office", resolution: "1280x720" });
await vm.connect(); // open the control channel before driving the VM
await vm.keyboard.type("hello");
const png = await vm.screenshot();
await vm.kill();Create a sandbox
import { SandboxClient } from "@solarisdk/sandbox";
const client = new SandboxClient({
apiKey: process.env.SOLARI_API_KEY!,
baseUrl: "https://api.getsolari.com",
});
const sbx = await client.create({ template: "base" });
const r = await sbx.commands.run("echo", { args: ["hi"] });
console.log(r.stdout); // "hi"
await sbx.kill();All three at once
SolariClient from @solarisdk/sdk wraps a DesktopClient, a SandboxClient, a TemplateClient, and a VolumeClient behind one API key. Browsers keep their own client.
import { SolariClient } from "@solarisdk/sdk";
const solari = new SolariClient({ apiKey: process.env.SOLARI_API_KEY! });
const vm = await solari.desktops.create({ template: "office" });
const sbx = await solari.sandboxes.create({ template: "base" });
const vol = await solari.volumes.create({ name: "datasets" });Configuration
Every client takes its options as one constructor object. apiKey is always required.
| Option | Type | Default | Client | Notes |
|---|---|---|---|---|
apiKey | string | required | all | Sent as Authorization: Bearer. Throws if empty. |
baseUrl | string | see notes | all | Solari: resolved from region; setting it ignores region. DesktopClient / SandboxClient: required. SolariClient: https://api.getsolari.com. |
region | SolariRegion | "us-west" | Solari | Only "us-west" today. Unknown region throws. |
timeoutMs | number | 90_000 | Solari | Per attempt, not per call. |
maxAttempts | number | 2 | Solari | Total attempts. 2 means one retry. |
backoffMs | number | 500 | Solari | Fixed sleep between attempts, not exponential. |
callTimeoutMs | number | transport default | DesktopClient, SandboxClient, SolariClient | Per-RPC timeout given to handles this client creates. |
fetch | typeof fetch | global | DesktopClient, SandboxClient, SolariClient | Override for tests or non-standard runtimes. |
No environment variables are read
No SDK constructor reads
process.env. Pass apiKey (and baseUrl where required) explicitly. The process.env.SOLARI_API_KEY above is your code, not the SDK’s. Only the solari CLI reads SOLARI_API_KEY and SOLARI_BASE_URL.Retry policy (@solarisdk/browser)
HTTP requests retry on 502, 503, and 504 only, with a fixed
backoffMs pause. Other statuses return as-is. launch()’s own retries option is separate: it re-creates the session with linear 100ms × attempt backoff and does not govern sessions.create().Reference
| Class | Package | Purpose |
|---|---|---|
Solari | @solarisdk/browser | Browser entry point: sessions, profiles, replays. |
BrowserSession | @solarisdk/browser | A live browser + its session. Returned by launch(). |
DesktopClient | @solarisdk/desktop | VM entry point: create, connect, pause, resume, destroy. |
Desktop | @solarisdk/desktop | A live GUI session: mouse, keyboard, screenshots, apps. |
SandboxClient | @solarisdk/sandbox | Sandbox entry point: create, list, snapshots, volumes. |
Sandbox | @solarisdk/sandbox | A live headless session: commands, code, files, git. Shared base of Desktop. |
SolariClient | @solarisdk/sdk | Unified wrapper: .desktops, .sandboxes, .templates, .volumes. |
