Quickstart
Sprites are cloud VMs that feel like persistent dev environments. You can run commands, install packages, create files—and everything stays exactly how you left it. Unlike containers that reset each time, Sprites remember your entire filesystem between sessions.
The magic: when you’re not using your Sprite, it goes to sleep. Send a command or HTTP request, and it wakes up instantly. Everything is right where you left it.
This guide will walk you through creating your first Sprite. In just a few minutes, you’ll have a persistent development environment that responds to HTTP traffic and remembers everything between runs.
Install the CLI
Section titled “Install the CLI”Install with our install script (macOS/Linux):
curl -fsSL https://sprites.dev/install.sh | shThis script auto-detects your platform, verifies checksums, and installs the latest Sprite CLI to ~/.local/bin.
For Windows or manual installation, see CLI Installation.
Verify installation:
sprite --helpAuthenticate
Section titled “Authenticate”Sprites uses your Fly.io account for authentication:
sprite org authThis opens a browser window to authenticate with Fly.io.
If authentication fails, try running fly auth logout followed by fly auth login first, then retry sprite org auth.
Create Your First Sprite
Section titled “Create Your First Sprite”sprite create my-first-spriteThis creates a new Sprite with default configuration, running and ready to accept commands.
Set it as your active Sprite to avoid adding -s my-first-sprite to every command:
sprite use my-first-spriteUse sprite list to see all your Sprites, or sprite destroy -s my-first-sprite when you’re done with one. You can have multiple Sprites running simultaneously—each with its own isolated environment.
Run Commands
Section titled “Run Commands”Execute commands in your Sprite:
# Run a simple commandsprite exec echo "Hello, Sprites!"
# Run multiple commandssprite exec "cd /tmp && ls -la"
# Open an interactive shellsprite consoleAuto-wakeup magic: When you’re not using your Sprite, it shuts down to save resources. When you run a command or hit its URL, it wakes up instantly—like magic. No manual starting or stopping required.
See Persistence in Action
Section titled “See Persistence in Action”Your Sprite comes pre-configured with common development tools (Node.js, Python, Go, Git, and more). Here’s the magic: everything you install or create persists between commands.
Check available runtimes
Section titled “Check available runtimes”See what’s already installed and ready to use:
sprite exec "node --version && python3 --version && go version"Install a package
Section titled “Install a package”Install dependencies just like you would locally—they’ll stick around:
sprite exec "pip install requests"Create and read files
Section titled “Create and read files”Files you create persist across sessions. Write once, read anytime:
# Create a filesprite exec "echo 'Hello from my persistent Sprite!' > /home/sprite/greeting.txt"
# Disconnect, get coffee, come back later...# Everything is still there!sprite exec "cat /home/sprite/greeting.txt"sprite exec "python -c 'import requests; print(requests.__version__)'"Unlike containers that reset on each run, your Sprite keeps your installed packages, files, and entire filesystem intact.
Start a Web Server
Section titled “Start a Web Server”Every Sprite has a unique HTTP URL and can serve traffic. This makes it perfect for testing APIs, hosting prototypes, or running background services.
Serve HTTP
Section titled “Serve HTTP”Start a simple Python server and get your public URL:
# Start a simple HTTP server on port 8080sprite exec "python -m http.server 8080 &"
# Get your Sprite's public URLsprite urlVisit the URL in your browser—you’ll see Python’s directory listing page. Your Sprite automatically routes HTTP traffic to port 8080 and wakes up to handle requests.
By default, your Sprite’s URL requires authentication. To make it publicly accessible, run:
sprite url update --auth publicThe default sprite auth mode allows access using a Sprite token with Bearer authentication.
Test on-demand wake-up
Section titled “Test on-demand wake-up”Here’s where it gets cool. Close your terminal, wait a minute, then visit the URL again. Your Sprite wakes up automatically to serve the request. That’s the magic of on-demand wakeup—no manual starting or stopping required.
You’ve got a working Sprite! You’ve created a persistent environment, installed packages, created files, and served HTTP traffic—all of which will be there next time you connect. Try cloning a repo, running a build, or deploying a tiny HTTP service to see what else you can do.
Using the SDKs
Section titled “Using the SDKs”The CLI is perfect for day-to-day development, but if you’re building tools, automation workflows, or integrating Sprites into your application, the SDKs give you programmatic control. Use them to dynamically create environments, orchestrate workloads, or embed Sprites into your product.
import { SpritesClient } from '@fly/sprites';
const client = new SpritesClient(process.env.SPRITE_TOKEN);
const sprite = await client.createSprite('my-sprite');
// Execute a commandconst result = await sprite.execFile('python', ['-c', "print('hello')"]);console.log(result.stdout);
// Stream output from long-running commandsconst cmd = sprite.spawn('bash', ['-c', 'for i in {1..10}; do date +%T; sleep 0.5; done']);for await (const line of cmd.stdout) { process.stdout.write(line);}
await sprite.delete();package main
import ( "context" "fmt" "io" "os"
sprites "github.com/superfly/sprites-go")
func main() { ctx := context.Background() client := sprites.New(os.Getenv("SPRITE_TOKEN"))
sprite, _ := client.CreateSprite(ctx, "my-sprite", nil) defer client.DeleteSprite(ctx, "my-sprite")
// Execute a command cmd := sprite.Command("python", "-c", "print('hello')") output, _ := cmd.Output() fmt.Println(string(output))
// Stream output from long-running commands cmd = sprite.Command("bash", "-c", "for i in {1..10}; do date +%T; sleep 0.5; done") stdout, _ := cmd.StdoutPipe() cmd.Start() io.Copy(os.Stdout, stdout) cmd.Wait()}client = Sprites.new(System.get_env("SPRITE_TOKEN"))
{:ok, sprite} = Sprites.create(client, "my-sprite")
# Execute a command{output, 0} = Sprites.cmd(sprite, "python", ["-c", "print('hello')"])IO.puts(output)
# Stream output from long-running commandssprite|> Sprites.stream("bash", ["-c", "for i in {1..10}; do date +%T; sleep 0.5; done"])|> Stream.each(&IO.write/1)|> Stream.run()
Sprites.destroy(sprite)