Skip to main content
Both client libraries are pre-1.0 and have separate versioning. This changelog documents updates to modal-js and modal-go.
The SDKs migrated from github.com/modal-labs/libmodal to github.com/modal-labs/modal-client in the unreleased version.
  • Updated Sandbox methods to wait for newly created sandboxes to be ready and not error immediately when it’s not available yet
  • Fixed a bug in modal-js so that canceling sandbox.stdout or sandbox.stderr cleans up background resources
  • Updated Sandbox (JS) to raise a better error when the sandbox was terminated
  • Fixed regression in Sandbox.exec (JS) where it threw a ChannelCredentials type error
Sandbox improvements:
  • Added Sandbox.MountImage (Go) and Sandbox.mountImage (JS) that mounts an Image to a path in the Sandbox’s filesystem
  • Added Sandbox.SnapshotDirectory (Go) and Sandbox.snapshotDirectory (JS) that snapshots and creates a new image from a directory in the running sandbox
  • Upgraded Sandbox.Exec (Go) and Sandbox.exec (JS) bringing improved performance and reliability
  • Added a Sandbox.Detach (Go) or sandbox.detach (JS) to disconnect your client from the sandbox and clean up any resources associated with the connection
    • Strongly recommend calling Detach after you are done interacting with the sandbox
    • Detach does not close streams from Sandbox.Stdout (Go) or Sandbox.stdout (JS). These streams should be closed using their Close (Go) or close (JS) methods
  • Sandbox.Terminate (Go) and Sandbox.terminate (JS) detaches by default
    • To interact with a running sandbox after terminating, use Sandboxes.FromID (Go) or sandboxes.fromId (JS) to create a new Sandbox object
  • Sandbox.Terminate now accepts a wait parameter to wait for the sandbox to terminate and return the exit code
Breaking changes:
  • Changed Sandbox.Terminate in Go which now returns (int, error). The int is the return code when &SandboxTerminateParams{Wait: true} is passed in
  • Added a Sandbox.Detach requirement - strongly recommend calling Detach after you are done interacting with the sandbox
  • Fixed a bug where deleting a Volume, Queue, or Secret with allowMissing=true could still raise a NOT_FOUND error
  • Improved handling of degraded HTTP/2 connections, which addresses intermittent RST_STREAM errors
  • In JS, improves reliability for reading streams from sandbox.stdout and sandbox.stderr
  • Added custom domains to Sandboxes.Create in Go and sandboxes.create in JS
    • Note that Sandbox custom domains work differently from Function custom domains and must currently be set up manually by Modal; please get in touch if this feature interests you
  • Added enable_docker experimental option to Sandbox.Create to Go and Sandbox.create to JS
Breaking changes:Changed Sandbox parameter defaults to be consistent with the Python SDK:
  • Set default Sandbox timeout to 5 minutes (was previously 10 minutes in the JS SDK)
  • Leave the Sandbox entrypoint args empty by default in the JS SDK (was previously ["sleep", "48h"])
  • Added Sandbox.CreateConnectToken to Go and Sandbox.createConnectToken to JS
  • Enabled goroutine leak detection for all tests by default
  • Fixed a few remaining goroutine leaks
  • Test clean-ups: ensure we always terminate Sandboxes, close ephemeral objects, etc.
  • Added debug logging to CloudBucketMount creation in Go, bringing it in line with the JS SDK
  • Updated the API for creating CloudBucketMounts in JS, using the same modal.cloudBucketMounts.create() pattern as other Modal objects, bringing it in line with the Go SDK
  • Aligned the way the JS/Go SDKs handle empty/missing fields in gRPC messages, so the behavior is identical to the Python SDK
  • Enabled goleak for goroutine leak detection in tests
  • Fixed all detected goroutine leaks in Sandboxes and Images
  • Added deletion methods for Volume and Secret objects and updated the deletion methods on Queue objects to support idempotent deletion via the allowMissing parameter
  • Fixed a bug in modal-go where Sandbox.Exec would leak goroutines
  • Allow adding custom gRPC interceptors when creating a Modal client, to allow instrumentation, custom telemetry, etc.
  • All Go SDK functions that take a Context will respect the timeout of the context
  • Improved the error message when calling a webhook Function as a normal Function
  • Allow customizing the config file path via MODAL_CONFIG_PATH environment variable (defaults to ~/.modal.toml)
  • Added support for passing MODAL_LOGLEVEL=debug environment variable to also log debug logs, incl. all gRPC calls, etc.
The first beta release of the Modal SDKs for JS and Go (graduating from alpha). See the Migration Guide for a detailed list of breaking changes.
Major changes:
  • The SDKs now expose a central Modal Client object as the main entry point for interacting with Modal resources
  • The interface for working with Modal object instances (Functions, Sandboxes, Images, etc.) is largely the same as before, with some naming changes
  • Calling deployed Functions and classes now uses a new protocol for payload serialization which requires the deployed apps to use the Modal Python SDK 1.2 or newer
  • Internally removed the global client (and config/profile data in global scope), moving all that to the Client type
  • Consistent parameter naming across both SDKs: all Options structs/interfaces renamed to Params
JavaScript-specific changes:
  • Added explicit unit suffixes to all parameters that represent durations (in milliseconds, suffixed with Ms) or memory amounts (in MiB, suffixed with MiB)
Go-specific changes:
  • Changed how we do context passing, so contexts now only affect the current operation and are not used for lifecycle management of the created resources
  • All Params structs are now passed as pointers for consistency and to support optional parameters
  • Field names follow Go casing conventions (e.g., IdID, UrlURL, TokenIdTokenID)
  • Added explicit unit suffixes to all parameters that represent memory amounts (in MiB, suffixed with MiB)
Additional features:
  • Added support for setting CPU and memory limits when creating Sandboxes and Cls instances
  • Fixed a bug in modal-js related to unpickling objects from Python (Function calls, Queues, etc.), where integers between 32678 and 65535 were incorrectly decoded as signed integers
  • Internal updates for how authentication tokens are handled for input plane clients
  • Added env parameters to several methods, as a convenience for passing environment variables into Sandboxes, etc.
  • Added Sandbox.getTags() (JS) and Sandbox.GetTags() (Go)
  • Added support for PTYs in Sandboxes
  • Added Image.dockerfileCommands() (JS) and ImageDockerfileCommands() (Go)
  • Added support for setting idle timeout when creating Sandboxes
  • Added Image.delete() (JS) and ImageDelete() (Go)
  • Changed Image.fromId() (JS) and NewImageFromId() (Go) to throw a NotFoundError if the Image does not exist
    • Note that the signature of NewImageFromId() has changed
  • Sandbox.exec in JS now correctly accepts a list of Secrets
New features:
  • Added Image.build (JS) and Image.Build (Go)
  • Added Image.fromId (JS) / NewImageFromId (Go)
  • Added support for instantiating a Cls with custom options, using Cls.withOptions()/.withConcurrency()/.withBatching() (JS) / Cls.WithOptions()/.WithConcurrency()/.WithBatching() (Go)
  • Added support for Named Sandboxes
  • Added support for Volume.ephemeral() (JS) / VolumeEphemeral() (Go)
  • Operations on an ephemeral Queue after having called CloseEphemeral() will now explicitly fail in Go
Sandbox enhancements: Added support for more parameters to Sandbox.create():
  • blockNetwork: Whether to block all network access from the Sandbox
  • cidrAllowlist: List of CIDRs the Sandbox is allowed to access
  • gpu: GPU reservation for the Sandbox (e.g. “A100”, “T4:2”, “A100-80GB:4”)
  • cloud: Cloud provider to run the Sandbox on
  • regions: Region(s) to run the Sandbox on
  • verbose: Enable verbose logging
  • proxy: Connect a Modal Proxy to a Sandbox
  • workdir: Set the working directory
Image improvements:
  • Added support for mounting CloudBucketMounts to Sandboxes
  • Added top level for Image objects that are lazy. The Images are built when creating a Sandbox:
    • Image.fromRegistry in typescript and NewImageFromRegistry in golang
    • Image.fromAwsEcr in typescript and NewImageFromAwsEcr in golang
    • Image.fromGcpArtifactRegistry in typescript and NewImageFromGcpArtifactRegistry in golang
Other additions:
  • Added Secret.fromObject() (JS) / SecretFromMap() (Go) to create a Secret from key-value pairs (like from_dict() in Python)
  • Added name field to Apps, Sandboxes, Secrets, Volumes, and Queues
  • Added support for Function.getCurrentStats() (JS) / Function.GetCurrentStats() (Go)
  • Added support for Function.updateAutoscaler() (JS) / Function.UpdateAutoscaler() (Go)
  • Added support for Function.getWebURL() (JS) / Function.GetWebURL() (Go)
  • Added support for Volume.readOnly() (JS) / Volume.ReadOnly() (Go)
  • Added support for setting tags on Sandboxes, and for listing Sandboxes (by tag)
  • Added support for getting Sandboxes from an ID
  • Added support for snapshotting the filesystem of a Sandbox
  • Added support for polling Sandboxes to check if they are still running, or get the exit code
  • Added support to execute commands in Sandboxes with Secrets
  • Added support for creating Sandboxes with Secrets
  • Added support for setting up Tunnels to expose live TCP ports for Sandboxes
  • Fixed calls of Cls with experimental input_plane_region option
  • (Go) Removed Function.InputPlaneURL from being exposed as public API
  • Added support for passing a Secret to imageFromRegistry() (JS) / ImageFromRegistry() (Go) to pull images from private registries
  • Added support for creating Images from Google Artifact Registry with imageFromGcpArtifactRegistry() (JS) / ImageFromGcpArtifactRegistry() (Go)
  • Added experimental support for calling remote Functions deployed with the input_plane_region option in Python
  • Added InitializeClient() (Go) / initializeClient() (JS) to initialize the client at runtime with credentials
  • Client libraries no longer panic at startup if no token ID / Secret is provided. Instead, they will throw an error when trying to use the client
  • Added workdir and timeout options to ExecOptions for Sandbox processes
  • Added support for Sandbox filesystem
  • Added support for CommonJS format / require(). Previously, modal-js only supported ESM import
  • Added support for creating Images from AWS ECR with App.imageFromAwsEcr() (JS) / App.ImageFromAwsEcr() (Go)
  • Added support for accessing Modal Secrets with Secret.fromName() (JS) / modal.SecretFromName() (Go)
  • Fixed serialization of some pickled objects (negative ints, dicts) in modal-js
Queue support:
  • Added support for the Queue object to manage distributed FIFO queues
    • Queues have a similar interface as Python, with put() and get() being the primary methods
    • You can put structured objects onto Queues, with limited support for the pickle format
  • Added InvalidError, QueueEmptyError, and QueueFullError to support Queues
  • Fixed a bug in modal-js that produced incorrect bytecode for bytes objects
  • Options in the Go SDK now take pointer types, and can be nil for default values
  • Added support for spawning Functions with Function_.spawn() (JS) / Function.Spawn() (Go)
  • Added feature for looking up and calling remote classes via the Cls object
  • (Go) Removed the initial ctx context.Context argument from Function.Remote()
  • Support calling remote Functions with arguments greater than 2 MiB in byte payload size
First public release with basic Function, Sandbox, Image, and ContainerProcess support.

Build docs developers (and LLMs) love