Fly.io Sprites
Executes commands in persistent Fly.io Sprites through the official @fly/sprites SDK. A Sprite is a Linux VM that keeps its filesystem between runs and hibernates on its own when idle. SpritesSandbox gets or creates a Sprite by name, so a new process can reconnect to the same files. Supports command execution with streaming output, timeouts, cancellation, background processes with stdin, and checkpoint capture. For interface details, see WorkspaceSandbox interface.
InstallationDirect link to Installation
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/sprites
pnpm add @mastra/sprites
yarn add @mastra/sprites
bun add @mastra/sprites
@mastra/sprites requires Node.js 24 or later because the @fly/sprites SDK does.
Set your Sprites API token in one of three ways.
- Shell export
- .env file
- Constructor
export SPRITES_TOKEN=your-api-token
SPRITES_TOKEN=your-api-token
new SpritesSandbox({ token: 'your-api-token' })
UsageDirect link to Usage
Add a SpritesSandbox to a workspace and assign it to an agent:
import { Agent } from '@mastra/core/agent'
import { Workspace } from '@mastra/core/workspace'
import { SpritesSandbox } from '@mastra/sprites'
const workspace = new Workspace({
sandbox: new SpritesSandbox({
id: 'mastra-project',
// token read from SPRITES_TOKEN
}),
})
const agent = new Agent({
id: 'code-agent',
name: 'Code Agent',
instructions: 'You are a coding assistant working in this workspace.',
model: 'anthropic/claude-sonnet-4-6',
workspace,
})
const response = await agent.generate(
'Print "Hello, world!" and show the current working directory.',
)
console.log(response.text)
Reusing a SpriteDirect link to Reusing a Sprite
The id is the Sprite name. On start(), SpritesSandbox looks up a Sprite with that name and reconnects to it, or creates one when none exists. Files written in an earlier session are still there:
const first = new SpritesSandbox({ id: 'mastra-project' })
await first.executeCommand('sh', ['-c', 'echo hello > notes.txt'])
await first.stop()
// Later, possibly in another process
const second = new SpritesSandbox({ id: 'mastra-project' })
const result = await second.executeCommand('cat', ['notes.txt'])
console.log(result.stdout) // hello
Any existing Sprite with the same name in your account is adopted, so choose names that are unique to the project. When id is omitted, a random name is generated.
spriteConfig (RAM, CPUs, region, storage) is only applied when the Sprite is created.
Stopping and destroyingDirect link to Stopping and destroying
stop() and destroy() do different things:
stop()kills background processes started by this instance and closes the SDK connection. The Sprite and its filesystem are kept. Sprites hibernate on their own when idle, so there is nothing to suspend.destroy()permanently deletes the Sprite and its filesystem. It works without callingstart()first, and a Sprite that no longer exists is treated as already deleted.
const sandbox = new SpritesSandbox({ id: 'mastra-project' })
// Remove the Sprite when the project is finished
await sandbox.destroy()
CheckpointsDirect link to Checkpoints
snapshot() captures a checkpoint of the Sprite's current state and waits for the capture to finish:
await sandbox.snapshot()
Checkpoints live inside the Sprite. They can't be used to boot or seed another sandbox, so supportsCheckpoints is false and SpritesSandbox doesn't implement clone(). Use the @fly/sprites SDK through sandbox.sprite to list or restore checkpoints.
Streaming outputDirect link to Streaming output
Pass onStdout and onStderr to receive output as it arrives:
await sandbox.executeCommand('npm', ['install'], {
onStdout: data => process.stdout.write(data),
onStderr: data => process.stderr.write(data),
timeout: 120_000,
})
When a command times out or its abortSignal fires, the command is killed and the result reports killed: true.
Constructor parametersDirect link to Constructor parameters
id?:
token?:
baseURL?:
spriteConfig?:
timeout?:
env?:
workingDirectory?:
instructions?:
PropertiesDirect link to Properties
id:
name:
provider:
status:
sprite:
@fly/sprites Sprite for direct SDK access. Throws SandboxNotReadyError if the sandbox has not been started.processes:
MethodsDirect link to Methods
stop:
destroy:
snapshot:
Background processesDirect link to Background processes
SpritesSandbox includes a process manager for spawning and managing background processes. Each process runs in its own Sprites exec session and supports stdin.
const sandbox = new SpritesSandbox({ id: 'mastra-project' })
await sandbox.start()
const handle = await sandbox.processes.spawn('node server.js', {
env: { PORT: '3000' },
onStdout: data => console.log(data),
})
await handle.sendStdin('reload\n')
await handle.kill()
Processes started by one SpritesSandbox instance are not visible to another instance, and stop() kills them.
See SandboxProcessManager reference for the full API.
Editor providerDirect link to Editor provider
Register the provider with MastraEditor to hydrate stored sandbox configs into runtime instances:
import { MastraEditor } from '@mastra/editor'
import { spritesSandboxProvider } from '@mastra/sprites'
const editor = new MastraEditor({
sandboxes: { [spritesSandboxProvider.id]: spritesSandboxProvider },
})
See the Sandbox provider reference for details on registering custom sandbox providers.