Skip to main content
Modal provides serverless container infrastructure with GPU support. Best for ML/AI workloads and Python development.

Setup

npm install @langchain/modal

Authentication

Get your tokens from modal.com/settings/tokens.
export MODAL_TOKEN_ID=your_token_id
export MODAL_TOKEN_SECRET=your_token_secret
Or pass credentials directly:
const sandbox = await ModalSandbox.create({
  auth: {
    tokenId: "your-token-id",
    tokenSecret: "your-token-secret",
  },
});

Usage with deepagents

import { createDeepAgent } from "deepagents";
import { ChatAnthropic } from "@langchain/anthropic";
import { ModalSandbox } from "@langchain/modal";

const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  timeoutMs: 600_000, // 10 minutes
});

try {
  const agent = createDeepAgent({
    model: new ChatAnthropic({ model: "claude-sonnet-4-20250514" }),
    systemPrompt: "You are a coding assistant with sandbox access.",
    backend: sandbox,
  });

  const result = await agent.invoke({
    messages: [{ role: "user", content: "Install numpy and calculate pi" }],
  });
} finally {
  await sandbox.close();
}

Standalone usage

import { ModalSandbox } from "@langchain/modal";

const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  timeoutMs: 600_000,
});

const result = await sandbox.execute("python --version");
console.log(result.output);

await sandbox.close();

Configuration

OptionTypeDefaultDescription
imageNamestring"alpine:3.21"Docker image to use
timeoutMsnumber300000Max lifetime in milliseconds
workdirstring-Working directory
gpustring-GPU type ("T4", "A100", "H100", etc.)
cpunumber-CPU cores (fractional allowed)
memoryMiBnumber-Memory allocation in MiB
volumesRecord<string, string>-Volume name mappings (mount path to volume name)
secretsstring[]-Modal Secret names to inject
initialFilesRecord<string, string | Uint8Array>-Files to create on startup
envRecord<string, string>-Environment variables
blockNetworkboolean-Block network access
namestring-Sandbox name (unique within app)

GPU support

Modal supports NVIDIA GPUs for ML workloads:
const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  gpu: "T4",  // or "L4", "A10G", "A100", "H100"
});

Volumes and secrets

Mount Modal Volumes for persistent storage and inject secrets as environment variables:
// Volumes and secrets must be created in Modal first
const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  volumes: {
    "/data": "my-data-volume",
    "/models": "my-models-volume",
  },
  secrets: ["my-api-keys", "database-credentials"],
});

// Files in /data and /models persist across sandbox restarts
await sandbox.execute("echo 'Hello' > /data/test.txt");

// Secrets are available as environment variables
await sandbox.execute("echo $API_KEY");

Initial files

Pre-populate the sandbox with files during creation:
const sandbox = await ModalSandbox.create({
  imageName: "python:3.12-slim",
  initialFiles: {
    "/app/main.py": 'print("Hello from Python!")',
    "/app/config.json": JSON.stringify({ name: "my-app" }, null, 2),
  },
});

const result = await sandbox.execute("python /app/main.py");

Accessing the Modal SDK

For advanced features not exposed by BaseSandbox, access the underlying Modal SDK:
const modalSandbox = await ModalSandbox.create();

const client = modalSandbox.client;     // ModalClient
const instance = modalSandbox.instance;  // Sandbox

// Direct SDK operations
const process = await instance.exec(["python", "-c", "print('Hello')"], {
  stdout: "pipe",
  stderr: "pipe",
});

Reconnecting to existing sandboxes

// Reconnect by ID
const reconnected = await ModalSandbox.fromId(sandboxId);

// Reconnect by name
const reconnected2 = await ModalSandbox.fromName("my-app", "my-sandbox");

Factory functions

import { createModalSandboxFactory, createModalSandboxFactoryFromSandbox } from "@langchain/modal";

// Create new sandbox per invocation
const factory = createModalSandboxFactory({ imageName: "python:3.12-slim" });

// Or reuse an existing sandbox across invocations
const sandbox = await ModalSandbox.create();
const reuseFactory = createModalSandboxFactoryFromSandbox(sandbox);

Error handling

import { ModalSandboxError } from "@langchain/modal";

try {
  await sandbox.execute("some command");
} catch (error) {
  if (error instanceof ModalSandboxError) {
    switch (error.code) {
      case "NOT_INITIALIZED":
        await sandbox.initialize();
        break;
      case "COMMAND_TIMEOUT":
        console.error("Command took too long");
        break;
      case "AUTHENTICATION_FAILED":
        console.error("Check your Modal token credentials");
        break;
    }
  }
}

Error codes

CodeDescription
NOT_INITIALIZEDSandbox not initialized - call initialize()
ALREADY_INITIALIZEDCannot initialize twice
AUTHENTICATION_FAILEDInvalid or missing Modal tokens
SANDBOX_CREATION_FAILEDFailed to create sandbox
SANDBOX_NOT_FOUNDSandbox ID/name not found or expired
COMMAND_TIMEOUTCommand execution timed out
COMMAND_FAILEDCommand execution failed
FILE_OPERATION_FAILEDFile read/write failed
RESOURCE_LIMIT_EXCEEDEDCPU, memory, or storage limits exceeded
VOLUME_ERRORVolume operation failed

Environment variables

VariableDescription
MODAL_TOKEN_IDModal API token ID
MODAL_TOKEN_SECRETModal API token secret

Connect these docs to Claude, VSCode, and more via MCP for real-time answers.