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.
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
// 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()# 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
apiKeyoption, thenSOLARI_API_KEY, thenE2B_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, defaulthttps://api.getsolari.com.E2B_API_URLandE2B_DOMAINare 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
| E2B | On Solari | Notes |
|---|---|---|
Sandbox.create(template, opts) | Works | template is base, a name from Template.build, or a tpl_ id. metadata, envs and lifecycle work. |
timeoutMs | Differs | On 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, setTimeout | Works | connect resumes a paused sandbox. list filters by metadata and state. kill returns false for a sandbox that is already gone. |
pause() | Works | Keeps memory and disk. A filesystem-only pause is treated as a full pause. |
createSnapshot, listSnapshots, deleteSnapshot, fork | Works | Snapshots keep memory and disk. fork takes a snapshot and starts count new sandboxes from it. |
getHost(port) | Not supported | Use the extension getPreviewUrl(port), which returns the public URL. |
allowInternetAccess: false, network, iam, mcp | Not supported | Throws SolariCompatUnsupported. |
Commands, PTY and files
| E2B | On Solari | Notes |
|---|---|---|
commands.run | Works | Runs from the home directory in a login shell. A non-zero exit throws CommandExitError, as in E2B. |
commands.run (background), wait, kill, sendStdin | Works | closeStdin is not supported. list, kill and connect by pid work for commands started by the same process. |
pty.create, sendInput, resize, kill | Works | A shell that exits on its own is not observed; call kill. |
files.read, write, list, getInfo, exists, makeDir, rename, remove | Works | Relative paths resolve against the home directory. owner and group are empty. |
files.watchDir | Works | Event names are relative to the watched path. |
uploadUrl, downloadUrl | Works |
Code interpreter
| E2B | On Solari | Notes |
|---|---|---|
runCode (Python) | Works | State persists between calls. Results carry text, html, png, jpeg, svg, latex, json and markdown, plus logs and errors. |
runCode (bash) | Differs | Each call is a fresh shell. |
runCode (JavaScript, TypeScript, R, Java) | Not supported | The guest ships a Python kernel. |
onStdout, onStderr, onResult, onError | Differs | Called after the run finishes, not while it runs. |
createCodeContext, listCodeContexts, removeCodeContext, restartCodeContext | Differs | Solari cannot list or destroy kernels. list returns contexts created by this process, remove forgets one, and restart clears its variables. |
Templates
| E2B | On Solari | Notes |
|---|---|---|
Template().fromBaseImage, fromImage, fromPythonImage, fromNodeImage, fromTemplate | Works | Public registry images only. |
aptInstall, pipInstall, npmInstall, runCmd, copy, makeDir, gitClone, setWorkdir, setEnvs | Works | setEnvs persists in the template. |
Template.build, buildInBackground, getBuildStatus, exists | Works | name:latest is accepted. |
setStartCmd, setReadyCmd, setUser, fromDockerfile, private registries, tags | Not supported | Start 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.
