Install custom packages
Runra sandboxes start from a template image. For small or changing dependencies, install packages at runtime. For heavy or repeated dependencies, build a custom template and pass its template ID to Sandbox.create().
Prerequisites
Section titled “Prerequisites”- Completed the Quickstart.
RUNRA_API_KEYset in your environment.
Install Python packages
Section titled “Install Python packages”Use commands.run() to call pip inside the sandbox:
import { Sandbox } from "runra";
const sbx = await Sandbox.create({ timeout: 900 });
try { const install = await sbx.commands.run( "python -m pip install --quiet pandas requests", { timeoutMs: 120_000 } );
if (install.stderr) console.error(install.stderr);
const execution = await sbx.runCode(`import pandas as pdimport requests
print("pandas", pd.__version__)print("requests", requests.__version__)`);
console.log(execution.logs.stdout.join("\n"));} finally { await sbx.kill();}Install from requirements.txt
Section titled “Install from requirements.txt”await sbx.files.write( "/home/user/requirements.txt", "numpy\npandas\nscikit-learn\n");
await sbx.commands.run( "python -m pip install --quiet -r /home/user/requirements.txt", { timeoutMs: 180_000 });Install Node packages
Section titled “Install Node packages”Create a working directory, initialize a package, and install dependencies:
await sbx.commands.run("mkdir -p /home/user/app");await sbx.files.write( "/home/user/app/package.json", JSON.stringify( { type: "module", dependencies: { zod: "latest", lodash: "latest", }, }, null, 2 ));
await sbx.commands.run("cd /home/user/app && npm install", { timeoutMs: 180_000,});
const result = await sbx.commands.run( "cd /home/user/app && node -e 'import { z } from \"zod\"; console.log(z.string().parse(\"ok\"))'");
console.log(result.stdout);Use a custom template for repeated dependencies
Section titled “Use a custom template for repeated dependencies”Runtime installation is simple but adds latency to every sandbox. If your agents always need the same dependencies, preinstall them in a template and pass the template ID at creation time:
const sbx = await Sandbox.create({ template: process.env.RUNRA_TEMPLATE_ID, timeout: 900,});You can also configure it once in the environment:
export RUNRA_TEMPLATE_ID=tpl_your_prebuilt_templateThen all Sandbox.create() calls use that template unless you override template explicitly.
Choosing runtime install vs templates
Section titled “Choosing runtime install vs templates”| Approach | Use when | Tradeoff |
|---|---|---|
| Runtime install | Dependencies change often or are small. | Slower startup for each sandbox. |
| Custom template | Dependencies are large or reused by many jobs. | Requires a build step when dependencies change. |
Best practices
Section titled “Best practices”- Pin versions for production workflows, for example
pandas==2.2.2. - Use longer command timeouts for package managers.
- Keep generated project files under
/home/user. - Cache heavy, stable dependencies in a template instead of reinstalling them in every sandbox.
- Do not bake secrets into templates. Pass secrets as environment variables at sandbox creation time:
const sbx = await Sandbox.create({ envs: { OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? "", },});