Solari

Migrate from E2B

@solarisdk/e2b-compat (TypeScript) and solari-e2b-compat (Python) expose the E2B sandbox and code-interpreter API on top of Solari sandboxes. Change the import, set a Solari API key, and keep your E2B code. Anything Solari cannot do throws a clear SolariCompatUnsupported error. The few options that are accepted but ignored (for example transport tuning such as requestTimeoutMs) are marked as ignored in each package’s COMPAT.md.

Not affiliated with E2B

These packages are not affiliated with, endorsed by, or sponsored by E2B. “E2B” is E2B’s product name and is used here only to describe API compatibility. The API shapes follow the MIT-licensed e2b and @e2b/code-interpreter SDKs.

Switch the import

TypeScriptts
// before: import { Sandbox } from "@e2b/code-interpreter"
import { Sandbox } from "@solarisdk/e2b-compat/code-interpreter"

const sbx = await Sandbox.create() // reads SOLARI_API_KEY
const run = await sbx.runCode("x = 1\nx + 1")
console.log(run.text) // "2"

const r = await sbx.commands.run("echo hello")
console.log(r.stdout)
await sbx.files.write("/tmp/a.txt", "hi")
await sbx.kill()
Pythonpython
# before: from e2b_code_interpreter import Sandbox
from solari_e2b.code_interpreter import Sandbox

sbx = Sandbox.create()  # reads SOLARI_API_KEY
run = sbx.run_code("x = 1\nx + 1")
print(run.text)  # "2"

print(sbx.commands.run("echo hello").stdout)
sbx.files.write("/tmp/a.txt", "hi")
sbx.kill()

For code that imports the plain e2b package, use @solarisdk/e2b-compat (TypeScript) or solari_e2b (Python). The async API (AsyncSandbox) is available in Python.

Configuration

  • API key. The apiKey option, then SOLARI_API_KEY, then E2B_API_KEY. Only a Solari key (slr_…) is ever used. An E2B key left in the environment is skipped with a warning and is never sent to Solari.
  • Base URL. SOLARI_BASE_URL, default https://api.getsolari.com. E2B_API_URL and E2B_DOMAIN are honoured only when they point at Solari or loopback, so your Solari key can never reach E2B’s servers.

The code-interpreter template

@e2b/code-interpreter runs in a template with a data-analysis stack. The Solari equivalent is called code-interpreter-v1 and is built into your organization the first time you call Sandbox.create() without a template. The one-time build takes about 80 seconds and is billed as a template build; two processes that both find it missing each start a build, so prebuild it once. It installs pandas, numpy, scipy, scikit-learn, scikit-image, seaborn, matplotlib, plotly, bokeh and other common libraries; E2B’s very large audio, language and computer-vision packages (spacy, librosa, opencv, numba, gensim) are not included. Build it ahead of time with buildCodeInterpreterTemplate() (Python: build_code_interpreter_template_sync(), or await build_code_interpreter_template()), or point SOLARI_CODE_INTERPRETER_TEMPLATE at a template of your own.

What works

Sandbox lifecycle

E2BOn SolariNotes
Sandbox.create(template, opts)Workstemplate is base, a name from Template.build, or a tpl_ id. metadata, envs and lifecycle work.
timeoutMsDiffersOn Solari this is a rolling idle window that resets on use, not a fixed lifetime. The default is 5 minutes, as in E2B.
Sandbox.connect, list, getInfo, kill, setTimeoutWorksconnect resumes a paused sandbox. list filters by metadata and state. kill returns false for a sandbox that is already gone.
pause()WorksKeeps memory and disk. A filesystem-only pause is treated as a full pause.
createSnapshot, listSnapshots, deleteSnapshot, forkWorksSnapshots keep memory and disk. fork takes a snapshot and starts count new sandboxes from it.
getHost(port)Not supportedUse the extension getPreviewUrl(port), which returns the public URL.
allowInternetAccess: false, network, iam, mcpNot supportedThrows SolariCompatUnsupported.

Commands, PTY and files

E2BOn SolariNotes
commands.runWorksRuns from the home directory in a login shell. A non-zero exit throws CommandExitError, as in E2B.
commands.run (background), wait, kill, sendStdinWorkscloseStdin is not supported. list, kill and connect by pid work for commands started by the same process.
pty.create, sendInput, resize, killWorksA shell that exits on its own is not observed; call kill.
files.read, write, list, getInfo, exists, makeDir, rename, removeWorksRelative paths resolve against the home directory. owner and group are empty.
files.watchDirWorksEvent names are relative to the watched path.
uploadUrl, downloadUrlWorks

Code interpreter

E2BOn SolariNotes
runCode (Python)WorksState persists between calls. Results carry text, html, png, jpeg, svg, latex, json and markdown, plus logs and errors.
runCode (bash)DiffersEach call is a fresh shell.
runCode (JavaScript, TypeScript, R, Java)Not supportedThe guest ships a Python kernel.
onStdout, onStderr, onResult, onErrorDiffersCalled after the run finishes, not while it runs.
createCodeContext, listCodeContexts, removeCodeContext, restartCodeContextDiffersSolari cannot list or destroy kernels. list returns contexts created by this process, remove forgets one, and restart clears its variables.

Templates

E2BOn SolariNotes
Template().fromBaseImage, fromImage, fromPythonImage, fromNodeImage, fromTemplateWorksPublic registry images only.
aptInstall, pipInstall, npmInstall, runCmd, copy, makeDir, gitClone, setWorkdir, setEnvsWorkssetEnvs persists in the template.
Template.build, buildInBackground, getBuildStatus, existsWorksname:latest is accepted.
setStartCmd, setReadyCmd, setUser, fromDockerfile, private registries, tagsNot supportedStart processes after Sandbox.create with a background command.

Not supported

E2B’s network rules, MCP gateway, IAM tokens, Volume and Secret APIs, template tags, webhooks and lifecycle-event APIs have no Solari equivalent in these packages. The full matrix, with every call, is in the COMPAT.md that ships with each package.