Programs
A Modal.Sandbox is a program Alchemy bundles into an image. Every sandbox you start from it runs the program, serving HTTP on a port you reach through the sandbox’s tunnel.
Each sandbox runs its own copy
Section titled “Each sandbox runs its own copy”The program’s code lives in the image. Its environment, including the token its bindings use, lives in a Modal Secret attached to every sandbox:
agent-1Sandbox · from MySandbox
MySandboxBun · :8080
envModal Secret
Write the program
Section titled “Write the program”import * as Modal from "@alchemy.run/modal";import * as Effect from "effect/Effect";import * as HttpServerResponse from "effect/http/HttpServerResponse";import { Coder } from "./Coder.ts";
export default class MySandbox extends Modal.Sandbox<MySandbox>()( "MySandbox", { main: import.meta.url, app: Coder }, Effect.gen(function* () { return { fetch: Effect.succeed(HttpServerResponse.text("ready")), }; }),) {}Run alchemy deploy. Modal builds the image; you don’t need Docker.
Start one and call it
Section titled “Start one and call it”const sandboxes = yield* Modal.CreateSandbox(MySandbox);const sandbox = yield* sandboxes.create({ timeout: "10 minutes" });const port = yield* sandbox.getTcpPort();const response = yield* port.fetch(HttpClientRequest.get("/"));Provide Modal.CreateSandboxHttp. getTcpPort() is the program’s port, reached through the sandbox’s tunnel.
Use bindings from the program
Section titled “Use bindings from the program”const models = yield* Modal.ReadVolume(Models);The token the binding needs is in the program’s env, never in the image.
Run a plain Node program
Section titled “Run a plain Node program”import * as Modal from "@alchemy.run/modal";import { Coder } from "./Coder.ts";
export const MySandbox = Modal.Sandbox("MySandbox", { main: "./src/agent-server.ts", app: Coder, env: { GREETING: "hello" },});export type MySandboxEnv = Modal.InferEnv<typeof MySandbox>;import { createServer } from "node:http";import type { MySandboxEnv } from "./MySandbox.ts";
const env = process.env as unknown as MySandboxEnv;
createServer((_request, response) => response.end(env.GREETING)).listen(Number(process.env.PORT));It runs on Bun. Listen on PORT (8080 unless you set port).