Install custom packages
Add Python and Node dependencies to a Runra sandbox.
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
- Completed the Quickstart.
RUNRA_API_KEYset in your environment.
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 pd
import requests
print("pandas", pd.__version__)
print("requests", requests.__version__)
`);
console.log(execution.logs.stdout.join("\n"));
} finally {
await sbx.kill();
}
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
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
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_template
Then all Sandbox.create() calls use that template unless you override template explicitly.
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
- 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 ?? "",
},
});