SDKs & Languages
Every Solari SDK speaks the same gateway wire protocol, so you can drive a sandbox or VM from the language your project already lives in. TypeScript and Python are at full parity; Go, Rust, and C++ ship the core surface: create and connect a session plus the commands, files, code.run, and git namespaces, with more to follow.
For a feature-by-feature comparison of all five languages, see the SDK feature matrix.
Solari, while the sandbox and VM SDKs export SandboxClient and DesktopClient, so check the install line matches the product you want. Browser users: start at Quickstart and Sessions.Requirements
- Node: 18+ for
@solarisdk/sandboxand@solarisdk/desktop. - Python: 3.9+.
await using(compiled TypeScript 5.2+; the syntax runs uncompiled only on Node 24) and Python'sasync with awaitrelease a sandbox or VM when the scope ends, from@solarisdk/sandbox0.4.0 /@solarisdk/desktop0.2.0 andsolari-sandbox0.6.0 /solari-desktop0.6.0. On older versions, usetry/finallyand callkill(). Browsers: see Quickstart.
Availability
| Language | Package / module | Surface |
|---|---|---|
| TypeScript | @solarisdk/sandbox, @solarisdk/desktop | Full: computer-use, PTY, viewer, snapshots |
| Python | solari-sandbox, solari-desktop | Full: computer-use, PTY, viewer, snapshots |
| Go | github.com/solari-sdk/solari-sandbox-go | Core: commands, files, code, git |
| Rust | solari-sandbox | Core: commands, files, code, git |
| C++ (17) | solari:: (CMake) | Core: commands, files, code, git |
Each binding is idiomatic for its language. Go is context-first with typed error values, Rust is async/tokio returning Result<T, SolariError>, and C++ is a blocking API over libcurl + a WebSocket client + nlohmann/json. The same API key authenticates every one of them.
TypeScript
npm install @solarisdk/sandboximport { SandboxClient } from "@solarisdk/sandbox"
const sandboxes = new SandboxClient({
apiKey: process.env.SOLARI_API_KEY!,
// baseUrl is optional and defaults to https://api.getsolari.com
})
const sbx = await sandboxes.create({ template: "base" })
const res = await sbx.commands.run("echo", { args: ["hello", "world"] })
console.log(res.exitCode, res.stdout)
await sbx.kill()Use SandboxClient (or DesktopClient) when you need just one product. Use SolariClient from @solarisdk/sdk when one script drives sandboxes, VMs, templates and volumes with a single API key; it also ships the solari CLI. All of them default to the production gateway, so baseUrl is only needed for a non-production environment.
Python
pip install solari-sandboximport asyncio, os
from solari_sandbox import SandboxClient
async def main():
async with SandboxClient(
api_key=os.environ["SOLARI_API_KEY"],
) as sandboxes:
sbx = await sandboxes.create(template="base")
try:
await sbx.connect()
res = await sbx.commands.run("echo", args=["hello", "world"])
print(res.exitCode, res.stdout)
finally:
await sbx.kill()
asyncio.run(main())Go
go get github.com/solari-sdk/solari-sandbox-gopackage main
import (
"context"
"fmt"
"log"
solari "github.com/solari-sdk/solari-sandbox-go"
)
func main() {
ctx := context.Background()
client, err := solari.NewClient(solari.ClientOptions{
APIKey: "slr_live_…",
BaseURL: "https://api.getsolari.com",
})
if err != nil {
log.Fatal(err)
}
sb, err := client.Create(ctx, solari.CreateOptions{Template: "base"})
if err != nil {
log.Fatal(err)
}
defer sb.Kill(ctx)
// The first run rides the warm REST /exec fast path; call sb.Connect(ctx)
// to open the control WebSocket for streaming or interactive work.
res, err := sb.Commands.Run(ctx, "echo", solari.CommandOptions{
Args: []string{"hello", "world"},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("exit=%d stdout=%q\n", res.ExitCode, res.Stdout)
}Rust
# Cargo.toml
solari-sandbox = "0.1"use solari::{Client, ClientOptions, CreateOptions, RunOptions};
#[tokio::main]
async fn main() -> Result<(), solari::SolariError> {
let client = Client::new(ClientOptions::new(
"slr_live_…",
"https://api.getsolari.com",
))?;
let sbx = client
.create(CreateOptions { template: Some("base".into()), ..Default::default() })
.await?;
let out = sbx
.commands()
.run("echo", RunOptions::new().args(["hello world"]))
.await?;
println!("exit={} stdout={:?}", out.exit_code, out.stdout);
sbx.kill().await?;
Ok(())
}C++
The C++ binding is a CMake project; pull it in with FetchContent (it vendors libcurl + a WebSocket client + nlohmann/json). Build with SOLARI_WITH_WS=ON for streaming and interactive work.
#include <iostream>
#include <solari/solari.hpp>
int main() {
solari::ClientOptions opts;
opts.apiKey = "slr_live_...";
opts.baseUrl = "https://api.getsolari.com";
solari::Client client(opts);
auto sbx = client.create(); // POST /sandboxes
solari::CommandOptions o;
o.args = {"hello", "world"};
solari::CommandResult r = sbx->commands.run("echo", o);
std::cout << "exit " << r.exitCode << "\n" << r.stdout_;
sbx->kill();
}