Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

AlrikOlson/D2Sharp

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

D2Sharp

A .NET wrapper for D2, the modern diagram scripting language that turns text to diagrams.

NuGet codecov License

Features

  • Zero Configuration - Works out of the box with sensible defaults
  • High Performance - Built-in worker pool handles concurrent requests efficiently
  • Full D2 Support - All D2 features: layouts, themes, sketch mode, and more
  • Async/Await - Task-based async rendering with cancellation support
  • Cross-Platform - Windows, macOS, and Linux
  • Production Ready - Battle-tested with comprehensive error handling

Installation

dotnet add package D2Sharp

Quick Start

using D2Sharp;

// Create a renderer (uses 3 worker processes by default)
using var renderer = new D2Renderer();

// Render a diagram
var result = await renderer.RenderDiagramAsync("A -> B -> C");

if (result.IsSuccess)
{
    File.WriteAllText("diagram.svg", result.Svg);
}
else
{
    Console.WriteLine($"Error: {result.Error?.Message}");
}

That's it! D2Sharp handles all the complexity for you.

Basic Usage

Simple Diagrams

using var renderer = new D2Renderer();

var script = @"
server -> database: queries
database -> cache: reads
";

var result = await renderer.RenderDiagramAsync(script);

Error Handling

var result = await renderer.RenderDiagramAsync("A -> ");  // Invalid

if (!result.IsSuccess)
{
    var error = result.Error;
    Console.WriteLine($"Line {error.LineNumber}: {error.Message}");
    Console.WriteLine($"  {error.LineContent}");
}

Synchronous Rendering

var result = renderer.RenderDiagram("A -> B");  // Blocks until complete

Cancellation & Timeouts

// With cancellation token
var cts = new CancellationTokenSource();
var result = await renderer.RenderDiagramAsync(script, cancellationToken: cts.Token);

// The renderer handles timeouts automatically - diagrams that take too long
// will be cancelled and return an error result

Customization

Themes

var options = new RenderOptions
{
    ThemeId = 1  // Cool classics theme
};

var result = await renderer.RenderDiagramAsync("server -> database", options);

300+ themes available: View all D2 themes →

Layout Engines

var options = new RenderOptions
{
    Layout = LayoutEngine.Elk  // or LayoutEngine.Dagre (default)
};
  • Dagre - Fast, clean layouts (default)
  • ELK - More complex layouts with additional features

Sketch Mode

var options = new RenderOptions
{
    Sketch = true  // Hand-drawn style
};

Visual Options

var options = new RenderOptions
{
    Pad = 50,        // Padding (default: 100)
    Scale = 0.5,     // Scale factor
    Center = true    // Center in viewbox
};

Combined Example

var options = new RenderOptions
{
    Layout = LayoutEngine.Elk,
    ThemeId = 1,
    Sketch = true,
    Pad = 75
};

var result = await renderer.RenderDiagramAsync(complexDiagram, options);

Advanced Configuration

Custom Worker Count

// For high-concurrency scenarios
using var renderer = new D2Renderer(workerCount: 15);

The default (3 workers) is optimal for most use cases.

ASP.NET Core Integration

// In Program.cs - Basic registration (uses 10 workers by default)
builder.Services.AddD2Sharp();

// With fluent configuration
builder.Services.AddD2Sharp(d2 => d2
    .UseProcessPool(pool => pool.WithWorkerCount(15))
    .ConfigureCaching(cache => cache.Enabled = true)
    .ConfigureTelemetry(telemetry => telemetry.EnableMetrics = true));

// Or use direct mode for CLI tools (no process pool)
builder.Services.AddD2Sharp(d2 => d2.UseDirect());

// In your controller/endpoint
public class DiagramController : ControllerBase
{
    private readonly D2Renderer _renderer;

    public DiagramController(D2Renderer renderer)
    {
        _renderer = renderer;
    }

    [HttpPost]
    public async Task<IActionResult> Render([FromBody] string script)
    {
        var result = await _renderer.RenderDiagramAsync(script);
        return result.IsSuccess
            ? Content(result.Svg, "image/svg+xml")
            : BadRequest(result.Error);
    }
}

Configuration Options

The fluent builder API provides several configuration options:

Process Pool Configuration

builder.Services.AddD2Sharp(d2 => d2
    .UseProcessPool(pool => pool.WithWorkerCount(15)));  // Customize worker count

Caching Configuration

builder.Services.AddD2Sharp(d2 => d2
    .ConfigureCaching(cache =>
    {
        cache.Enabled = true;
        cache.MaxSize = 500;
        cache.Expiration = TimeSpan.FromMinutes(30);
    }));

Telemetry Configuration

builder.Services.AddD2Sharp(d2 => d2
    .ConfigureTelemetry(telemetry =>
    {
        telemetry.EnableTracing = true;
        telemetry.EnableMetrics = true;
        telemetry.EnableDiagnosticIds = true;
    }));

Concurrency Limits (Direct Mode Only)

builder.Services.AddD2Sharp(d2 => d2
    .UseDirect()
    .ConfigureConcurrency(concurrency =>
    {
        concurrency.MaxConcurrentRenders = 5;
    }));

Combined Configuration

builder.Services.AddD2Sharp(d2 => d2
    .UseProcessPool(pool => pool.WithWorkerCount(20))
    .ConfigureCaching(cache => cache.Enabled = true)
    .ConfigureTelemetry(telemetry => telemetry.EnableMetrics = true));

Direct Mode (CLI Tools)

For command-line tools or single-threaded applications where you don't need worker processes:

using var renderer = D2Renderer.CreateDirect();
var result = await renderer.RenderDiagramAsync(script);

Note: Direct mode is not recommended for web applications with concurrent requests.

D2 Language Reference

# Shapes and connections
server -> client: HTTPS

# Containers
network: {
  router
  switch
  router -> switch
}

# Styling
server.style.fill: "#4CAF50"
client.shape: person

# Direction
direction: right

Learn D2 syntax →

Performance

D2Sharp is optimized for production workloads:

  • Concurrent requests: Efficiently handled via worker pool
  • Memory efficient: Automatic cleanup and minimal allocations
  • Fast: Simple diagrams render in ~30-50ms

Typical performance (on Apple Silicon):

  • Simple diagrams: 30-50ms
  • Complex diagrams: 100-200ms
  • Very complex: 300-500ms

Building from Source

Prerequisites

  • .NET 8.0 SDK
  • Go 1.22+
  • GCC

Check dependencies:

# Windows
.\depcheck.ps1

# Unix/Linux/macOS
./depcheck.sh

Build

dotnet build

Project Structure

  • src/D2Sharp - Main library
  • src/D2Sharp.Abstractions - Shared interfaces and types
  • src/D2Sharp.Worker - Worker process for process isolation
  • examples/D2Sharp.Web - Web demo application
  • tests/D2Sharp.Tests - Unit tests
  • tests/D2Sharp.IntegrationTests - Integration tests

Additional Documentation

Links

License

MIT License - see LICENSE.txt for details.

Acknowledgments

  • D2 - The diagram scripting language
  • Built with .NET 8.0

About

D2Sharp wraps the D2 diagramming library for .NET, allowing you to render D2 diagrams with C# in your .NET applications.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Morty Proxy This is a proxified and sanitized view of the page, visit original site.