NSprites 0.6.0

dotnet add package NSprites --version 0.6.0
                    
NuGet\Install-Package NSprites -Version 0.6.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NSprites" Version="0.6.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NSprites" Version="0.6.0" />
                    
Directory.Packages.props
<PackageReference Include="NSprites" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NSprites --version 0.6.0
                    
#r "nuget: NSprites, 0.6.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NSprites@0.6.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NSprites&version=0.6.0
                    
Install as a Cake Addin
#tool nuget:?package=NSprites&version=0.6.0
                    
Install as a Cake Tool

Build Status Coverage NuGet Version .NET License

NSprites

A .NET client library for the Sprites.dev API.

Features

  • Full REST API Support: Create, manage, and delete sprites
  • Checkpoint Management: Create and restore filesystem snapshots
  • Command Execution: Run commands with streaming output
  • Port Tunneling: Forward local ports to sprite containers
  • Async/Await: Modern async API throughout
  • Strongly Typed: Full type safety with records and enums
  • Testable: Dependency injection friendly with mocked HTTP clients

Installation

dotnet add package NSprites

Quick Start

using NSprites;

// Create a client with your token
var client = new SpritesClient("your-sprites-token");

// Create a new sprite
var sprite = await client.CreateSpriteAsync(new CreateSpriteRequest("my-sprite"));
Console.WriteLine($"Created sprite: {sprite.Url}");

// Get an existing sprite client
var mySprite = client.Sprite("my-sprite");

// Run a command
var result = await mySprite.Exec.RunCommandAsync(
    new ExecuteRequest(new[] { "echo", "Hello, World!" }));

Console.WriteLine(result.Stdout); // "Hello, World!\n"

// Create a checkpoint
await foreach (var @event in mySprite.Checkpoints.CreateAsync("Before deployment"))
{
    Console.WriteLine($"Checkpoint: {@event.Data}");
}

// List checkpoints
var checkpoints = await mySprite.Checkpoints.ListAsync();
foreach (var cp in checkpoints)
{
    Console.WriteLine($"Checkpoint: {cp.Id} - {cp.Comment}");
}

// Create a port tunnel
var tunnel = await mySprite.Proxy.CreateTunnelAsync(
    remotePort: 3000,
    localPort: 8080
);

API Overview

Sprites

// List all sprites
var sprites = await client.ListSpritesAsync();

// Create a sprite
var sprite = await client.CreateSpriteAsync(new CreateSpriteRequest("my-app"));

// Get sprite details
var details = await client.Sprite("my-app").GetAsync();

// Update URL settings
await client.Sprite("my-app").UpdateUrlSettingsAsync("public");

// Delete a sprite
await client.Sprite("my-app").DeleteAsync();

Checkpoints

var checkpoints = client.Sprite("my-app").Checkpoints;

// Create a checkpoint with streaming events
await foreach (var @event in checkpoints.CreateAsync("Backup before deploy"))
{
    Console.WriteLine($"{@event.Type}: {@event.Data}");
}

// List checkpoints
var list = await checkpoints.ListAsync();

// Get specific checkpoint
var cp = await checkpoints.GetAsync("v1");

// Restore to a checkpoint
await foreach (var @event in checkpoints.RestoreAsync("v1"))
{
    Console.WriteLine($"{@event.Type}: {@event.Data}");
}

Command Execution

var exec = client.Sprite("my-app").Exec;

// Run a simple command
var result = await exec.RunCommandAsync(
    new ExecuteRequest(new[] { "python", "-c", "print(42)" }));

Console.WriteLine($"Exit code: {result.ExitCode}");
Console.WriteLine($"Output: {result.Stdout}");

// Run with environment variables
var result = await exec.RunCommandAsync(new ExecuteRequest(
    Command: new[] { "env" },
    Env: new[] { "MY_VAR=test" },
    Dir: "/tmp"
));

// List active sessions
var sessions = await exec.ListSessionsAsync();

// Kill a session
await foreach (var @event in exec.KillSessionAsync(123))
{
    Console.WriteLine($"{@event.Type}: {@event.Message}");
}

WebSocket Command Execution

For real-time streaming and interactive sessions, use the WebSocket exec client:

var wssExec = client.Sprite("my-app").WssExec;

// Start an interactive bash session
using var session = await wssExec.ExecuteAsync(new WssExecOptions(
    ["bash"],
    Tty: true,
    Stdin: true,
    Timeout: TimeSpan.FromMinutes(5)
));

// Send input
await session.Stdin.WriteAsync(Encoding.UTF8.GetBytes("echo Hello\n"));
await session.Stdin.FlushAsync();

// Stream stdout as it arrives (recommended for real-time processing)
await foreach (var data in session.GetStdoutAsync(cancellationToken))
{
    var text = Encoding.UTF8.GetString(data);
    Console.WriteLine($"Output: {text}");

    // Stop when you see what you're looking for
    if (text.Contains("Hello"))
    {
        await session.Stdin.WriteAsync(Encoding.UTF8.GetBytes("exit\n"));
        await session.Stdin.FlushAsync();
        break;
    }
}

// Wait for command to complete
var exitMessage = await session.ExitTask;
Console.WriteLine($"Exit code: {exitMessage.ExitCode}");

Benefits of streaming API:

  • No race conditions - thread-safe by design
  • Real-time data consumption as it arrives
  • Modern, idiomatic C# API with await foreach
  • Multiple concurrent readers supported

Alternative approaches:

  1. Event callbacks: Subscribe to OnStdoutData / OnStderrData events
  2. Buffered stream access: Read from Stdout / Stderr streams after ExitTask completes

Note: Subscribe to events before calling ExecuteAsync() to avoid missing early data.

Port Tunneling

var proxy = client.Sprite("my-app").Proxy;

// Create a tunnel from local port 8080 to remote port 3000
var tunnel = await proxy.CreateTunnelAsync(
    remotePort: 3000,
    localPort: 8080,
    host: "localhost"
);

// Each local connection to localhost:8080 creates a new WebSocket to the sprite's port 3000
// The tunnel listener stays alive to handle multiple sequential connections

using var httpClient = new HttpClient();
var response = await httpClient.GetAsync("http://localhost:8080");

// When done, dispose the tunnel
tunnel.Dispose();

Each TCP connection creates its own WebSocket connection to the sprite for that specific session, making it suitable for testing web services, databases, or any networked applications running in sprites.

Running the Demo

See the NSprites.Demo project for a complete working example:

# Set your API token
export SPRITES_TOKEN=your-sprites-token

# Run the interactive bash demo
dotnet run --project NSprites.Demo <sprite-name>

Error Handling

All API errors are wrapped in SpritesApiException:

try
{
    var sprite = await client.Sprite("nonexistent").GetAsync();
}
catch (SpritesApiException ex)
{
    Console.WriteLine($"API Error: {ex.ErrorCode} - {ex.Message}");
    // ErrorCode: NotFound, StatusCode: 404
}

Available error codes:

  • Unauthorized - Authentication required
  • Forbidden - Access denied
  • NotFound - Resource not found
  • Conflict - Resource conflict
  • ValidationError - Invalid request data
  • RateLimited - Too many requests
  • InternalServerError - Server error

Testing

Solid Test Coverage

UnitTests.webp

See the test files for examples of mocking HTTP responses.

Requirements

  • .NET 10.0+
  • Sprites.dev account and API token

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on NSprites:

Package Downloads
MonumentalSystems.Sprites

A Semantic Kernel plugin for Sprites containerized development environment integration. Provides tools for managing sprites, executing commands, creating checkpoints, and establishing port forwarding tunnels.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.6.0 112 2/15/2026
0.5.3-alpha.0.15 46 2/15/2026
0.5.0 91 1/18/2026
0.4.0 94 1/18/2026
0.3.1 92 1/18/2026
0.2.2 94 1/18/2026
0.2.1 91 1/18/2026
0.2.0 92 1/18/2026
0.1.9 92 1/17/2026
0.1.8 89 1/17/2026
0.1.7 92 1/17/2026
0.1.6 92 1/17/2026
0.1.4 94 1/17/2026