Skip to main content
The Modal client is the main entry point for interacting with Modal resources from Go. It provides services for managing Apps, Sandboxes, Functions, Images, and other Modal resources.

Creating a client

The simplest way to create a client is using the default configuration:
import modal "github.com/modal-labs/modal-client/go"

mc, err := modal.NewClient()
if err != nil {
	log.Fatalf("Failed to create client: %v", err)
}
This reads credentials from environment variables (MODAL_TOKEN_ID and MODAL_TOKEN_SECRET) or the ~/.modal.toml configuration file.

Client with custom options

For more control, use NewClientWithOptions to customize the client:
client, err := modal.NewClientWithOptions(&modal.ClientParams{
	TokenID:     "ak-YOUR_TOKEN_ID",
	TokenSecret: "as-YOUR_TOKEN_SECRET",
	Environment: "main",
})
if err != nil {
	log.Fatalf("Failed to create client: %v", err)
}

Client parameters

The ClientParams struct supports several configuration options:
type ClientParams struct {
	// Authentication credentials
	TokenID     string
	TokenSecret string
	
	// Environment to connect to (defaults to "main")
	Environment string
	
	// Custom configuration (advanced use)
	Config      *config
	
	// Custom logger for debugging
	Logger      *slog.Logger
	
	// Custom gRPC client for testing
	ControlPlaneClient pb.ModalClientClient
	ControlPlaneConn   *grpc.ClientConn
	
	// Custom gRPC interceptors for telemetry
	GRPCUnaryInterceptors  []grpc.UnaryClientInterceptor
	GRPCStreamInterceptors []grpc.StreamClientInterceptor
}

Client services

The client exposes services for different Modal resource types:
// Get or create an app
app, err := mc.Apps.FromName(ctx, "my-app", &modal.AppFromNameParams{
	CreateIfMissing: true,
})

Custom observability

Add custom gRPC interceptors for telemetry, tracing, and observability:
import (
	"context"
	"log"
	"time"

	modal "github.com/modal-labs/modal-client/go"
	"google.golang.org/grpc"
)

// Custom unary interceptor for logging
func loggingInterceptor() grpc.UnaryClientInterceptor {
	return func(
		ctx context.Context,
		method string,
		req, reply interface{},
		cc *grpc.ClientConn,
		invoker grpc.UnaryInvoker,
		opts ...grpc.CallOption,
	) error {
		start := time.Now()
		err := invoker(ctx, method, req, reply, cc, opts...)
		log.Printf("gRPC call: %s, duration: %v, error: %v", method, time.Since(start), err)
		return err
	}
}

func main() {
	mc, err := modal.NewClientWithOptions(&modal.ClientParams{
		GRPCUnaryInterceptors: []grpc.UnaryClientInterceptor{
			loggingInterceptor(),
		},
	})
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	// Use client...
}
Custom interceptors are appended after Modal’s built-in interceptors. The Modal gRPC API is not considered a public API and can change without warning.

Closing the client

Always close the client when done to clean up gRPC connections:
mc, err := modal.NewClient()
if err != nil {
	log.Fatalf("Failed to create client: %v", err)
}
defer mc.Close()

// Use the client...

Client version

Get the SDK version:
version := mc.Version()
fmt.Printf("Modal Go SDK version: %s\n", version)

Migration from v0.4 to v0.5

The v0.5 release introduced breaking changes. Key differences:
1
Client initialization changed
2
Before (v0.4):
3
modal.InitializeClient(modal.ClientOptions{...})
4
After (v0.5):
5
modal.NewClient()
// or
modal.NewClientWithOptions(&modal.ClientParams{...})
6
Resources accessed via client services
7
Before (v0.4):
8
modal.AppLookup(ctx, "my-app", &modal.LookupOptions{...})
modal.SandboxFromId(ctx, "sb-123")
9
After (v0.5):
10
mc.Apps.FromName(ctx, "my-app", &modal.AppFromNameParams{...})
mc.Sandboxes.FromID(ctx, "sb-123")
11
Parameter structs renamed
12
All *Options types renamed to *Params and passed as pointers:
13
  • ClientOptionsClientParams
  • LookupOptionsAppFromNameParams, FunctionFromNameParams, etc.
  • SandboxOptionsSandboxCreateParams
  • ExecOptionsSandboxExecParams
  • 14
    Field naming follows Go conventions
    15
  • TokenIdTokenID
  • AppIdAppID
  • ServerUrlServerURL
  • See the migration guide for complete details.

    Build docs developers (and LLMs) love