High-performance TOON format serialization for .NET. Expression tree-based with zero reflection overhead. ArrayPool memory optimization, ConfigureAwait best practices. 449+ tests, 100% TOON v3.0 spec compliance. Perfect for AI/LLM token optimization, configuration files, and data exchange.
$ dotnet add package ToonNet.CoreTOON Data Format Serialization for .NET
AI-Optimized • Token-Efficient • Developer-Friendly
ToonNet is a .NET serialization library that provides:
TOON Format is a human-readable data format optimized for:
TOON Specification: This library implements TOON v3.0 (Date: 2025-11-24, Status: Working Draft)
ToonNet delivers production-grade performance with three critical advantages:
ToonNet is obsessively optimized for high-throughput, low-latency production environments:
Benchmark-Proven Speed (Apple M3 Max, .NET 8.0):
Payload Size Speed Improvement Memory Saved GC Pressure
───────────────────────────────────────────────────────────────
100 Bytes 1.16x faster 100% (0 alloc) ZERO ✅
1 KB 1.98x faster 100% (0 alloc) ZERO ✅
10 KB 2.37x faster 100% (0 alloc) ZERO ✅
100 KB 4.40x faster 99.99% saved ZERO ✅
Real-World Impact:
Architecture Excellence:
ConcurrentDictionary for concurrent scenarios// Hot path performance (after warmup)
var toon = ToonSerializer.Serialize(largeObject);
// 100KB payload: ~3.7μs, 2 bytes allocated (vs 16.4μs, 133KB with GetBytes)
// That's 340% faster with 99.99% less memory! 🚀
Performance Guarantee: All numbers are real BenchmarkDotNet measurements, not estimates. ToonNet is benchmarked on every release to prevent regressions.
TOON format uses significantly fewer tokens than JSON, reducing AI API costs:
// Example: Product catalog for AI prompt
var products = new List<Product>
{
new() { Id = 1, Name = "Laptop", Price = 1299.99m, InStock = true },
new() { Id = 2, Name = "Mouse", Price = 29.99m, InStock = true },
new() { Id = 3, Name = "Keyboard", Price = 89.99m, InStock = false }
};
string json = ToonConvert.SerializeToJson(products);
string toon = ToonSerializer.Serialize(products);
Console.WriteLine($"JSON tokens: ~{json.Length / 4}"); // ~150 tokens
Console.WriteLine($"TOON tokens: ~{toon.Length / 4}"); // ~90 tokens
// 40% token reduction = 40% cost savings on AI APIs
JSON output (longer, more tokens):
[{"id":1,"name":"Laptop","price":1299.99,"inStock":true},{"id":2,"name":"Mouse","price":29.99,"inStock":true},{"id":3,"name":"Keyboard","price":89.99,"inStock":false}]
TOON output (shorter, fewer tokens):
products[3]:
- Id: 1
Name: Laptop
Price: 1299.99
InStock: true
- Id: 2
Name: Mouse
Price: 29.99
InStock: true
- Id: 3
Name: Keyboard
Price: 89.99
InStock: false
Real-world savings:
ToonNet is engineered for extreme performance in production environments:
Zero-Allocation Hot Paths:
ConcurrentDictionary for type metadataLatest Optimizations (v1.3.0):
// ArrayPool optimization - Near-zero allocations
using var stream = new MemoryStream();
await ToonSerializer.SerializeToStreamAsync(data, stream);
// 10KB: 901ns, 13KB allocated (vs 1,454ns, 27KB with old approach)
// Result: 1.61x faster, 50% less memory, ZERO GC pressure ✅
Production-Ready Async:
Architecture highlights:
Thread-Safety:
ToonSerializer methods are safe to call from multiple threads.ConcurrentDictionary for safe concurrent access.ToonSerializerOptions instance concurrently across threads.When to use ToonNet: High-throughput APIs, real-time systems, AI/LLM applications, microservices with tight latency budgets. Benchmark-proven 2-4x faster than traditional serializers.
ToonNet is modular - install only what you need:
# Core package (required)
dotnet add package ToonNet.Core
# JSON support (for AI/LLM token optimization)
dotnet add package ToonNet.Extensions.Json
# YAML support
dotnet add package ToonNet.Extensions.Yaml
# ASP.NET Core integration
dotnet add package ToonNet.AspNetCore
dotnet add package ToonNet.AspNetCore.Mvc
# Performance (source generators)
dotnet add package ToonNet.SourceGenerators
# Core package (required)
dotnet add package ToonNet.Core
# For JSON conversion (AI/LLM use cases)
dotnet add package ToonNet.Extensions.Json
using ToonNet.Core.Serialization;
using ToonNet.Extensions.Json; // For JSON conversion
// Your C# class for AI prompt context (no attributes needed)
public class UserContext
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Interests { get; set; }
public List<Purchase> RecentPurchases { get; set; }
}
public class Purchase
{
public string Product { get; set; }
public decimal Amount { get; set; }
}
var context = new UserContext
{
Name = "Alice",
Age = 28,
Interests = new List<string> { "AI", "Machine Learning", "Photography" },
RecentPurchases = new List<Purchase>
{
new() { Product = "Camera Lens", Amount = 450.00m },
new() { Product = "ML Course", Amount = 99.99m }
}
};
// Serialize to TOON for AI prompt (uses fewer tokens than JSON)
string toonContext = ToonSerializer.Serialize(context);
// Use in your LLM prompt
var prompt = $@"
User Profile:
{toonContext}
Generate personalized product recommendations.
";
// Or deserialize back
var restored = ToonSerializer.Deserialize<UserContext>(toonContext);
Output (TOON format - compact, AI-friendly):
Name: Alice
Age: 28
Interests[3]: AI, Machine Learning, Photography
RecentPurchases[2]:
- Product: Camera Lens
Amount: 450.00
- Product: ML Course
Amount: 99.99
Token savings: ~40% fewer tokens than JSON = lower AI API costs!
That's it - no configuration, no attributes, just works.
ToonNet provides 6 core methods with familiar System.Text.Json-style naming:
// Serialize object to TOON string
string toon = ToonSerializer.Serialize(myObject);
// Deserialize TOON string to object
var obj = ToonSerializer.Deserialize<MyClass>(toonString);
Note: JSON conversion methods are in
ToonNet.Extensions.Jsonpackage. Addusing ToonNet.Extensions.Json;
// Convert JSON string to TOON string
string toon = ToonConvert.FromJson(jsonString);
// Convert TOON string to JSON string
string json = ToonConvert.ToJson(toonString);
// Parse JSON directly to C# object (via TOON)
var obj = ToonConvert.DeserializeFromJson<MyClass>(jsonString);
// Serialize C# object directly to JSON
string json = ToonConvert.SerializeToJson(myObject);
Architecture Note: ToonNet uses a layered approach for JSON interop:
ToonJsonConverter - Low-level conversion between JsonElement ↔ ToonDocument/ToonValue. Used internally as the core conversion engine.ToonConvert - High-level, developer-friendly API (similar to Newtonsoft's JsonConvert). Provides simple string-based conversions and internally uses ToonJsonConverter.This separation of concerns ensures clean architecture: ToonJsonConverter handles the conversion logic, while ToonConvert provides an ergonomic interface familiar to .NET developers.
using ToonNet.Extensions.Yaml;
// YAML string → TOON string
string toon = ToonYamlConvert.FromYaml(yamlString);
// TOON string → YAML string
string yaml = ToonYamlConvert.ToYaml(toonString);
Note: YAML support requires ToonNet.Extensions.Yaml package.
Architecture Note: Similar to JSON extensions, YAML package uses a layered approach:
ToonYamlConverter - Low-level conversion engine (YAML nodes ↔ ToonDocument)ToonYamlConvert - High-level string-based API (developer-friendly)Complete method reference:
| Method | Package | Input | Output | Use Case |
|---|---|---|---|---|
Serialize<T>(obj) | Core | C# Object | TOON string | Save objects as TOON |
Deserialize<T>(toon) | Core | TOON string | C# Object | Load TOON into objects |
FromJson(json) | Extensions.Json | JSON string | TOON string | Convert JSON to TOON |
ToJson(toon) | Extensions.Json | TOON string | JSON string | Convert TOON to JSON |
DeserializeFromJson<T>(json) | Extensions.Json | JSON string | C# Object | Parse JSON via TOON |
SerializeToJson<T>(obj) | Extensions.Json | C# Object | JSON string | Export as JSON |
FromYaml(yaml) | Extensions.Yaml | YAML string | TOON string | Convert YAML to TOON |
ToYaml(toon) | Extensions.Yaml | TOON string | YAML string | Convert TOON to YAML |
For large datasets (millions of records, database exports, ETL pipelines), ToonNet provides memory-efficient streaming serialization:
// Stream large dataset from database without loading all into memory
await ToonSerializer.SerializeStreamAsync(
items: dbContext.Users.AsAsyncEnumerable(),
filePath: "users_export.toon",
cancellationToken: cts.Token
);
// Read back with incremental deserialization
await foreach (var user in ToonSerializer.DeserializeStreamAsync<User>("users_export.toon"))
{
ProcessUser(user); // Memory-efficient: only one user in memory at a time
}
// Advanced: Custom separator mode and batch size
await ToonSerializer.SerializeStreamAsync(
items: GenerateLargeDatasetAsync(),
filePath: "export.toon",
options: null,
writeOptions: new ToonMultiDocumentWriteOptions
{
Mode = ToonMultiDocumentSeparatorMode.ExplicitSeparator, // Use "---" separator
DocumentSeparator = "---",
BatchSize = 100 // Buffer 100 items before writing (improves throughput)
},
cancellationToken: cts.Token
);
Use Cases:
Performance:
📖 Full API documentation: API-GUIDE.md
public class CustomerContext
{
public string Name { get; set; }
public List<Order> RecentOrders { get; set; }
public List<string> Preferences { get; set; }
}
public class Order
{
public string Id { get; set; }
public decimal Total { get; set; }
public string Status { get; set; }
}
var context = new CustomerContext
{
Name = "Alice Johnson",
RecentOrders = new List<Order>
{
new() { Id = "ORD-001", Total = 299.99m, Status = "Delivered" },
new() { Id = "ORD-002", Total = 149.50m, Status = "Shipped" }
},
Preferences = new List<string> { "Electronics", "Fast Shipping", "Eco-Friendly" }
};
// Serialize for AI prompt - uses fewer tokens than JSON
string promptContext = ToonSerializer.Serialize(context);
// Send to AI API with reduced token usage
var aiPrompt = $@"
Customer context:
{promptContext}
Generate personalized product recommendations.
";
// Result: 40% fewer tokens = 40% lower AI API costs
Output (compact, AI-friendly):
Name: Alice Johnson
RecentOrders[2]:
- Id: ORD-001
Total: 299.99
Status: Delivered
- Id: ORD-002
Total: 149.50
Status: Shipped
Preferences[3]: Electronics, Fast Shipping, Eco-Friendly
public class DocumentChunk
{
public string Id { get; set; }
public string Content { get; set; }
public Dictionary<string, string> Metadata { get; set; }
}
// Retrieved chunks from vector database
var chunks = new List<DocumentChunk>
{
new()
{
Id = "doc_123_chunk_1",
Content = "ToonNet provides efficient serialization...",
Metadata = new() { ["source"] = "docs", ["page"] = "1" }
}
};
// Serialize chunks for LLM context - minimal tokens
string context = ToonSerializer.Serialize(chunks);
// Use in RAG prompt with reduced token count
var ragPrompt = $"Context:\n{context}\n\nQuestion: How does ToonNet work?";
public class DatabaseConfig
{
public string Host { get; set; }
public int Port { get; set; }
public string Database { get; set; }
public bool UseSSL { get; set; }
}
// Load from file
var toonContent = await File.ReadAllTextAsync("database.toon");
var config = ToonSerializer.Deserialize<DatabaseConfig>(toonContent);
// Use configuration
var connectionString = $"Host={config.Host};Port={config.Port};Database={config.Database}";
database.toon:
Host: db.example.com
Port: 5432
Database: myapp_production
UseSSL: true
// Convert existing JSON to token-efficient TOON for AI prompts
var jsonResponse = await httpClient.GetStringAsync("https://api.example.com/data");
var toonData = ToonConvert.FromJson(jsonResponse);
// Use TOON data in AI prompt (fewer tokens)
var aiPrompt = $"Analyze this data:\n{toonData}";
// Or convert back to JSON for other APIs
var jsonForExport = ToonConvert.ToJson(toonData);