Blazing.Json.Queryable
1.0.0
See the version list below for details.
dotnet add package Blazing.Json.Queryable --version 1.0.0
NuGet\Install-Package Blazing.Json.Queryable -Version 1.0.0
<PackageReference Include="Blazing.Json.Queryable" Version="1.0.0" />
<PackageVersion Include="Blazing.Json.Queryable" Version="1.0.0" />
<PackageReference Include="Blazing.Json.Queryable" />
paket add Blazing.Json.Queryable --version 1.0.0
#r "nuget: Blazing.Json.Queryable, 1.0.0"
#:package Blazing.Json.Queryable@1.0.0
#addin nuget:?package=Blazing.Json.Queryable&version=1.0.0
#tool nuget:?package=Blazing.Json.Queryable&version=1.0.0
Blazing.Json.Queryable
Table of Contents
- Overview
- Key Features
- Why Choose Blazing.Json.Queryable?
- Getting Started
- Usage
- Supported LINQ Methods
- How It Works
- Performance Advantages
- Samples
- Give a ⭐
- Support
- History
Overview
Blazing.Json.Queryable is a high-performance LINQ provider for JSON data that processes JSON directly without full deserialization. Unlike traditional approaches that load entire JSON files into memory and then apply LINQ queries, this library processes JSON as a stream, providing dramatic performance improvements and memory efficiency for medium to large JSON files.
This custom JSON LINQ provider supports standard string, UTF-8, streaming, and advanced streaming JSONPath operations. Whether you're working with multi-megabyte API responses, large data exports, or log files, Blazing.Json.Queryable enables you to query JSON data efficiently with the familiar LINQ syntax you already know.
Key Features
- ✅ Direct JSON Processing: Query JSON without full deserialization
- ✅ Memory Efficient: Process files larger than available RAM
- ✅ Early Termination: Stop reading after finding required results (Take, First, Any)
- ✅ Streaming Support: Native
IAsyncEnumerable<T>for real-time processing - ✅ UTF-8 Native: Zero-allocation UTF-8 processing with Span<T>
- ✅ JSONPath Support: Navigate complex JSON structures efficiently
- ✅ Full LINQ: Comprehensive LINQ method support (60+ operations)
- ✅ .NET 10 Async LINQ: Built-in async LINQ with async predicates and transformations
- ✅ Multiple Input Formats: String, Stream, UTF-8 bytes, and more
Why Choose Blazing.Json.Queryable?
Performance Advantages Over Traditional JSON + LINQ
When working with medium to large JSON files, the traditional approach of deserializing to objects and then querying has significant disadvantages:
Traditional Approach:
// Traditional: Load ALL data into memory, then query
var json = File.ReadAllText("large-file.json"); // Load entire file
var all = JsonSerializer.Deserialize<List<Person>>(json); // Deserialize ALL records
var results = all.Where(p => p.Age > 25).Take(10).ToList(); // Query in-memory
Blazing.Json.Queryable Approach:
// Blazing.Json.Queryable: Stream and query simultaneously
await using var stream = File.OpenRead("large-file.json");
var results = await JsonQueryable<Person>.FromStream(stream)
.Where(p => p.Age > 25)
.Take(10)
.AsAsyncEnumerable()
.ToListAsync(); // Only deserializes matching records!
Key Advantages
| Feature | Traditional | Blazing.Json.Queryable |
|---|---|---|
| Memory Usage | Loads entire file | Constant memory usage |
| Early Exit | Processes all records | Stops after Take(N) |
| Large Files | OutOfMemoryException risk | Handles files > RAM |
| Speed (Large + Take) | Slow (full deserialize) | 10-20x faster |
| Async Support | Manual implementation | Native IAsyncEnumerable |
| UTF-8 Processing | String conversion overhead | Zero-allocation Span<T> |
When to Use Each Approach
✅ Use Blazing.Json.Queryable When:
- Files are > 10 MB
- You need early termination (Take, First, Any)
- Working in memory-constrained environments
- Processing files larger than available RAM
- Building async/streaming APIs
- Need real-time data processing
✅ Use Traditional JsonSerializer + LINQ When:
- Files are < 1 MB
- You need all data (no early termination)
- Simplicity is the priority
- Working with in-memory collections
Getting Started
Installation
Install via NuGet Package Manager:
<PackageReference Include="Blazing.Json.Queryable" Version="1.0.0" />
Or via the .NET CLI:
dotnet add package Blazing.Json.Queryable
Or via the Package Manager Console:
Install-Package Blazing.Json.Queryable
Requirements
- .NET 10.0 or later
- System.Text.Json (included with .NET)
- Utf8JsonAsyncStreamReader - Provides JSONPath support for token-based filtering (NuGet Package)
- Automatically included as a dependency
- Enables efficient JSONPath navigation:
$.data[*],$.users[*].orders[*], etc.
Quick Start
using Blazing.Json.Queryable.Providers;
// From JSON string
var jsonString = """[{"Name":"Alice","Age":30},{"Name":"Bob","Age":25}]""";
var results = JsonQueryable<Person>.FromString(jsonString)
.Where(p => p.Age > 25)
.ToList();
// From file stream (memory-efficient)
await using var stream = File.OpenRead("data.json");
var streamResults = await JsonQueryable<Person>.FromStream(stream)
.Where(p => p.Age > 25)
.Take(10)
.AsAsyncEnumerable()
.ToListAsync();
// From UTF-8 bytes (zero-allocation)
byte[] utf8Json = Encoding.UTF8.GetBytes(jsonString);
var utf8Results = JsonQueryable<Person>.FromUtf8(utf8Json)
.Where(p => p.Age > 25)
.ToList();
public record Person(string Name, int Age);
Usage
Basic Queries
Standard LINQ operations work as expected:
var json = """
[
{"Id":1,"Name":"Alice","Age":30,"City":"London","IsActive":true},
{"Id":2,"Name":"Bob","Age":25,"City":"Paris","IsActive":true},
{"Id":3,"Name":"Charlie","Age":35,"City":"London","IsActive":false}
]
""";
// Filtering
var adults = JsonQueryable<Person>.FromString(json)
.Where(p => p.Age >= 18)
.ToList();
// Projection
var names = JsonQueryable<Person>.FromString(json)
.Select(p => p.Name)
.ToList();
// Ordering
var sorted = JsonQueryable<Person>.FromString(json)
.OrderBy(p => p.Age)
.ThenBy(p => p.Name)
.ToList();
// Aggregation
var avgAge = JsonQueryable<Person>.FromString(json)
.Average(p => p.Age);
var totalActive = JsonQueryable<Person>.FromString(json)
.Count(p => p.IsActive);
// Combined operations
var results = JsonQueryable<Person>.FromString(json)
.Where(p => p.Age >= 25 && p.City == "London")
.OrderByDescending(p => p.Age)
.Select(p => new { p.Name, p.Age })
.Take(5)
.ToList();
Streaming Queries
Process large files with constant memory usage:
// Traditional approach - loads entire file into memory
var traditionalResults = new List<Person>();
var allJson = File.ReadAllText("huge-dataset.json"); // Loads ALL 500MB
var allPeople = JsonSerializer.Deserialize<List<Person>>(allJson); // Deserializes ALL
traditionalResults = allPeople.Where(p => p.Age > 25).Take(100).ToList();
// Blazing.Json.Queryable - streams and stops early
var streamingResults = new List<Person>();
await using (var stream = File.OpenRead("huge-dataset.json"))
{
await foreach (var person in JsonQueryable<Person>.FromStream(stream)
.Where(p => p.Age > 25)
.Take(100) // Stops reading after 100 matches!
.AsAsyncEnumerable())
{
streamingResults.Add(person);
}
}
// Result: 10-20x faster, uses constant memory
Advanced Streaming with .NET 10 Async LINQ
.NET 10 includes built-in async LINQ support, enabling powerful async transformations:
await using var stream = File.OpenRead("data.json");
// Async predicates - call async methods in Where clauses
await foreach (var person in JsonQueryable<Person>.FromStream(stream)
.AsAsyncEnumerable()
.Where(async (p, ct) => await IsValidUserAsync(p, ct)) // Async predicate!
.OrderBy(p => p.Name)
.Take(100))
{
Console.WriteLine(person.Name);
}
// Async transformations with Select
await foreach (var enriched in JsonQueryable<Person>.FromStream(stream)
.AsAsyncEnumerable()
.Select(async (p, ct) => await EnrichPersonDataAsync(p, ct)) // Async select!
.Where(p => p.Score > 50))
{
await ProcessAsync(enriched);
}
// Cancellation support
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5));
await foreach (var item in JsonQueryable<Person>.FromStream(stream)
.AsAsyncEnumerable()
.WithCancellation(cts.Token))
{
// Automatically cancelled after 5 minutes
}
UTF-8 Direct Processing
Process UTF-8 bytes without string conversion overhead:
// From UTF-8 byte array
byte[] utf8Json = Encoding.UTF8.GetBytes(jsonString);
var results = JsonQueryable<Person>.FromUtf8(utf8Json)
.Where(p => p.Age > 25)
.ToList();
// From ReadOnlySpan<byte> (zero-allocation)
ReadOnlySpan<byte> utf8Span = utf8Json.AsSpan();
var spanResults = JsonQueryable<Person>.FromUtf8(utf8Span)
.Where(p => p.Age > 25)
.ToList();
// From UTF-8 stream (most efficient for large data)
await using var utf8Stream = File.OpenRead("data.json");
await foreach (var person in JsonQueryable<Person>.FromStream(utf8Stream)
.AsAsyncEnumerable())
{
// Process each person with zero string allocations
}
JSONPath Queries
Navigate complex nested JSON structures from API responses:
JSONPath Support: Powered by Utf8JsonAsyncStreamReader - a high-performance library for token-based JSON filtering with JSONPath expressions.
// Example: GitHub API-style response
using var httpClient = new HttpClient();
var apiResponse = await httpClient.GetStringAsync("https://api.example.com/v1/users/123");
Sample API response structure:
{
"status": "success",
"data": {
"user": {
"id": 123,
"username": "alice_dev",
"profile": {
"fullName": "Alice Developer",
"email": "alice@example.com",
"address": {
"city": "London",
"country": "UK",
"postalCode": "SW1A 1AA"
},
"metadata": {
"joinDate": "2024-01-15",
"verified": true
}
},
"repositories": [
{
"id": 1001,
"name": "awesome-project",
"stars": 1250,
"language": "C#",
"isPrivate": false
},
{
"id": 1002,
"name": "secret-work",
"stars": 45,
"language": "TypeScript",
"isPrivate": true
}
],
"organizations": [
{
"id": 5001,
"name": "TechCorp",
"role": "developer",
"projects": [
{ "id": 101, "name": "Enterprise API", "budget": 500000.00 },
{ "id": 102, "name": "Mobile App", "budget": 250000.00 }
]
}
]
}
}
}
}
Query repositories directly using JSONPath:
var publicRepos = JsonQueryable<Repository>
.FromString(apiResponse, "$.data.user.repositories[*]")
.Where(r => !r.IsPrivate && r.Stars > 100)
.OrderByDescending(r => r.Stars)
.ToList();
Console.WriteLine($"Found {publicRepos.Count} popular public repositories");
// Query nested organization projects
var largeProjects = JsonQueryable<Project>
.FromString(apiResponse, "$.data.user.organizations[*].projects[*]")
.Where(p => p.Budget > 200000)
.OrderByDescending(p => p.Budget)
.ToList();
Console.WriteLine($"Found {largeProjects.Count} high-budget projects");
// Query user profile data
var verifiedUser = JsonQueryable<UserProfile>
.FromString(apiResponse, "$.data.user.profile")
.Where(p => p.Metadata.Verified && p.Address.Country == "UK")
.FirstOrDefault();
if (verifiedUser != null)
{
Console.WriteLine($"Verified user: {verifiedUser.FullName} from {verifiedUser.Address.City}");
}
// Model classes
public record Repository(int Id, string Name, int Stars, string Language, bool IsPrivate);
public record Project(int Id, string Name, decimal Budget);
public record UserProfile(string FullName, string Email, Address Address, Metadata Metadata);
public record Address(string City, string Country, string PostalCode);
public record Metadata(string JoinDate, bool Verified);
Stream large API responses efficiently
await using var stream = await httpClient.GetStreamAsync("https://api.example.com/v1/users?page=1&limit=10000");
await foreach (var repo in JsonQueryable<Repository>
.FromStream(stream, "$.data.items[*].repositories[*]")
.Where(r => r.Language == "C#")
.Take(50)
.AsAsyncEnumerable())
{
Console.WriteLine($"C# Repository: {repo.Name} ({repo.Stars} stars)");
}
Supported LINQ Methods
Filtering Operations
| Method | Description | Example |
|---|---|---|
Where |
Filters elements based on a predicate | .Where(p => p.Age > 18) |
OfType<T> |
Filters elements by type | .OfType<Employee>() |
Projection Operations
| Method | Description | Example |
|---|---|---|
Select |
Projects each element to a new form | .Select(p => p.Name) |
SelectMany |
Flattens nested sequences | .SelectMany(p => p.Orders) |
Ordering Operations
| Method | Description | Example |
|---|---|---|
OrderBy |
Sorts elements in ascending order | .OrderBy(p => p.Age) |
OrderByDescending |
Sorts elements in descending order | .OrderByDescending(p => p.Age) |
ThenBy |
Secondary ascending sort | .ThenBy(p => p.Name) |
ThenByDescending |
Secondary descending sort | .ThenByDescending(p => p.Name) |
Reverse |
Reverses the order of elements | .Reverse() |
Quantifier Operations
| Method | Description | Example |
|---|---|---|
All |
Tests if all elements satisfy a condition | .All(p => p.Age >= 18) |
Any |
Tests if any element satisfies a condition | .Any(p => p.City == "London") |
Contains |
Tests if sequence contains an element | .Contains(person) |
SequenceEqual |
Tests if two sequences are equal | .SequenceEqual(other) |
Element Access Operations
| Method | Description | Example |
|---|---|---|
First |
Returns first element | .First() |
FirstOrDefault |
Returns first element or default | .FirstOrDefault() |
Last |
Returns last element | .Last() |
LastOrDefault |
Returns last element or default | .LastOrDefault() |
Single |
Returns the only element | .Single() |
SingleOrDefault |
Returns the only element or default | .SingleOrDefault() |
ElementAt |
Returns element at specified index | .ElementAt(5) |
ElementAtOrDefault |
Returns element at index or default | .ElementAtOrDefault(5) |
Aggregation Operations
| Method | Description | Example |
|---|---|---|
Count |
Counts elements | .Count() |
LongCount |
Counts elements (64-bit) | .LongCount() |
Sum |
Sums numeric values | .Sum(p => p.Salary) |
Average |
Calculates average | .Average(p => p.Age) |
Min |
Finds minimum value | .Min(p => p.Age) |
Max |
Finds maximum value | .Max(p => p.Salary) |
MinBy |
Finds element with minimum key value | .MinBy(p => p.Age) |
MaxBy |
Finds element with maximum key value | .MaxBy(p => p.Salary) |
Aggregate |
Applies custom accumulator | .Aggregate((a, b) => a + b) |
Set Operations
| Method | Description | Example |
|---|---|---|
Distinct |
Removes duplicate elements | .Distinct() |
DistinctBy |
Removes duplicates by key | .DistinctBy(p => p.Email) |
Union |
Combines two sequences | .Union(otherPeople) |
UnionBy |
Combines sequences by key | .UnionBy(other, p => p.Id) |
Intersect |
Finds common elements | .Intersect(otherPeople) |
IntersectBy |
Finds common elements by key | .IntersectBy(ids, p => p.Id) |
Except |
Finds elements not in second sequence | .Except(otherPeople) |
ExceptBy |
Finds elements not in second by key | .ExceptBy(ids, p => p.Id) |
Partitioning Operations
| Method | Description | Example |
|---|---|---|
Take |
Takes first N elements | .Take(10) |
TakeLast |
Takes last N elements | .TakeLast(10) |
TakeWhile |
Takes elements while condition is true | .TakeWhile(p => p.Age < 30) |
Skip |
Skips first N elements | .Skip(20) |
SkipLast |
Skips last N elements | .SkipLast(5) |
SkipWhile |
Skips elements while condition is true | .SkipWhile(p => p.Age < 18) |
Chunk |
Divides elements into chunks of specified size | .Chunk(10) |
Grouping Operations
| Method | Description | Example |
|---|---|---|
GroupBy |
Groups elements by key | .GroupBy(p => p.City) |
GroupJoin |
Groups and joins sequences | .GroupJoin(orders, ...) |
Join |
Joins two sequences | .Join(orders, ...) |
Conversion Operations
| Method | Description | Example |
|---|---|---|
ToList |
Converts to List<T> (synchronous) | .ToList() |
ToArray |
Converts to array (synchronous) | .ToArray() |
ToDictionary |
Converts to dictionary | .ToDictionary(p => p.Id) |
ToHashSet |
Converts to hash set | .ToHashSet() |
ToLookup |
Converts to lookup | .ToLookup(p => p.City) |
Cast<T> |
Casts elements to type | .Cast<Employee>() |
AsEnumerable |
Returns as IEnumerable<T> | .AsEnumerable() |
AsQueryable |
Returns as IQueryable<T> | .AsQueryable() |
AsAsyncEnumerable |
Returns as IAsyncEnumerable<T> for async operations | .AsAsyncEnumerable() |
Note: For async conversion operations, use .AsAsyncEnumerable() followed by .NET 10's built-in async LINQ methods:
await query.AsAsyncEnumerable().ToListAsync()- Async conversion to List<T>await query.AsAsyncEnumerable().ToArrayAsync()- Async conversion to arrayawait query.AsAsyncEnumerable().ToDictionaryAsync(...)- Async conversion to dictionary
Sequence Operations
| Method | Description | Example |
|---|---|---|
Concat |
Concatenates two sequences | .Concat(otherPeople) |
Append |
Appends element to end | .Append(person) |
Prepend |
Prepends element to start | .Prepend(person) |
Zip |
Combines sequences pairwise | .Zip(ages, (p, a) => ...) |
DefaultIfEmpty |
Returns default if empty | .DefaultIfEmpty() |
How It Works
Blazing.Json.Queryable uses a custom LINQ provider that translates LINQ expressions into efficient JSON processing operations:
- Expression Tree Analysis: LINQ queries are analyzed to build an execution plan
- Streaming JSON Parser: Uses
System.Text.Json.Utf8JsonReaderfor efficient parsing - JSONPath Navigation: Leverages Utf8JsonAsyncStreamReader for token-based filtering when JSONPath expressions are used
- Lazy Evaluation: Only processes JSON elements needed for the query
- Early Termination: Stops reading JSON as soon as query requirements are met
- Zero-Allocation UTF-8: Direct UTF-8 processing using
Span<byte>andReadOnlySpan<byte> - Async Enumeration: Native
IAsyncEnumerable<T>support for non-blocking I/O
Execution Flow Example
// Query: Find first 10 active users over 25 in London
var results = await JsonQueryable<Person>.FromStream(stream)
.Where(p => p.Age > 25)
.Where(p => p.City == "London")
.Where(p => p.IsActive)
.OrderBy(p => p.Name)
.Take(10)
.AsAsyncEnumerable()
.ToListAsync();
// Internal execution:
// 1. Build execution plan from LINQ expression tree
// 2. Open JSON stream and start parsing
// 3. For each JSON object:
// a. Check Age > 25 (filter early)
// b. Check City == "London" (filter)
// c. Check IsActive (filter)
// d. If all pass, deserialize to Person object
// e. Add to ordered buffer
// 4. Stop reading after 10th match (early termination!)
// 5. Return results without processing entire file
Performance Advantages
Real-World Performance Comparison
Scenario: 100,000 record JSON file (52MB), find first 10 matching records
| Approach | Time | Memory | Notes |
|---|---|---|---|
| Traditional | 1,200ms | 450MB | Loads entire file, deserializes all |
| Blazing.Json.Queryable | 120ms | 25MB | Streams, stops after 10 matches |
| Improvement | 10x faster | 18x less | 90% time reduction |
Key Performance Benefits
Early Termination:
- Traditional: Processes ALL 100K records
- Blazing.Json.Queryable: Stops after finding 10 matches
- Result: 10-20x faster for Take/First operations
Memory Efficiency:
- Traditional: Loads 52MB file + 450MB objects
- Blazing.Json.Queryable: Uses ~25MB constant memory
- Result: Can process files larger than available RAM
Zero-Allocation UTF-8:
- Traditional: UTF-8 → String → Object
- Blazing.Json.Queryable: UTF-8 → Object (direct)
- Result: Fewer allocations, less GC pressure
Async Streaming:
- Traditional: Blocking I/O during file read
- Blazing.Json.Queryable: Non-blocking async enumeration
- Result: Better scalability in web APIs
When Performance Gains Are Largest
- Large files (> 10MB): Bigger file = larger advantage
- Early termination (Take/First): Smaller N = larger speedup
- Complex filters: More filtering = more benefit from stream processing
- Memory constraints: Limited RAM = Blazing.Json.Queryable enables processing that's impossible traditionally
Samples
The library includes comprehensive sample projects demonstrating different usage patterns:
Sample Projects
All samples are located in the samples/Blazing.Json.Queryable.Samples directory:
- BasicQueries.cs - Fundamental LINQ operations (Where, Select, OrderBy, Take, Skip, First, Count, Any)
- AdvancedLinqOperationsSamples.cs - Advanced operations (Zip, Chunk, DistinctBy, ExceptBy, IntersectBy, UnionBy)
- StreamQueries.cs - Async streaming with
IAsyncEnumerable<T> - Utf8Queries.cs - Zero-allocation UTF-8 processing examples
- JsonPathSamples.cs - Complex JSONPath navigation
- ComplexGroupingSamples.cs - GroupBy, Join, and GroupJoin operations
- LargeDatasetSamples.cs - Memory-efficient large file processing
- PerformanceComparison.cs - Benchmarks comparing traditional vs streaming approaches
- AsyncQueries.cs - .NET 10 async LINQ with async predicates
- AdvancedScenarios.cs - Real-world patterns and best practices
Running the Samples
# Clone the repository
git clone https://github.com/gragra33/Blazing.Json.Queryable.git
cd Blazing.Json.Queryable
# Run the samples project
dotnet run --project samples/Blazing.Json.Queryable.Samples
The samples include:
- Interactive console menu
- Performance benchmarks with timing
- Memory usage comparisons
- Real-world scenarios
- Best practices demonstrations
Give a ⭐
If you like or are using this project to learn or start your solution, please give it a star. Thanks!
Also, if you find this library useful and you're feeling really generous, please consider buying me a coffee ☕.
Support
- Documentation: Full API documentation included in NuGet package
- Samples: Comprehensive samples in the repository
- Issues: Report bugs or request features on GitHub Issues
- Discussions: Ask questions on GitHub Discussions
History
V1.0.0 - 11 January, 2026
Initial Release - Full production release
Core Features:
- Custom LINQ provider for JSON with 60+ LINQ methods
- Direct JSON processing without full deserialization
- Early termination support for Take, First, Any operations
- Memory-efficient streaming for files larger than RAM
Input Format Support:
- Standard JSON strings
- UTF-8 byte arrays and spans (zero-allocation)
- File streams with async enumeration
- Advanced streaming with
IAsyncEnumerable<T>
LINQ Operations:
- Filtering: Where, OfType
- Projection: Select, SelectMany
- Ordering: OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse
- Quantifiers: All, Any, Contains, SequenceEqual
- Element Access: First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, ElementAt, ElementAtOrDefault
- Aggregation: Count, LongCount, Sum, Average, Min, Max, MinBy, MaxBy, Aggregate
- Set Operations: Distinct, DistinctBy, Union, UnionBy, Intersect, IntersectBy, Except, ExceptBy
- Partitioning: Take, TakeLast, TakeWhile, Skip, SkipLast, SkipWhile, Chunk
- Grouping: GroupBy, GroupJoin, Join
- Conversion: ToList, ToArray, ToDictionary, ToHashSet, ToLookup, Cast, AsEnumerable, AsQueryable, AsAsyncEnumerable
- Sequence: Concat, Append, Prepend, Zip, DefaultIfEmpty
.NET 10 Features:
- Built-in async LINQ support with async predicates
- Async transformations with Select
- Native cancellation token support
- Enhanced performance with latest runtime optimizations
Performance Optimizations:
- Zero-allocation UTF-8 processing with Span<T>
- Early termination (10-20x faster for Take/First on large files)
- Constant memory usage regardless of file size
- Efficient execution plan optimization
Advanced Capabilities:
- JSONPath support for nested JSON navigation
- Complex query translation and optimization
- Async streaming with proper cancellation
Documentation:
- Comprehensive README with examples
- Full XML documentation in NuGet package
- sample project with 10+ demonstrations of all features
- Performance comparison benchmarks
Quality Assurance:
- Comprehensive test coverage
- Real-world performance benchmarks
- Production-ready error handling
- Best practices implementation
License: MIT License - see LICENSE file for details
Copyright © 2026 Graeme Grant. All rights reserved.
| Product | Versions 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. |
-
net10.0
- Utf8JsonAsyncStreamReader (>= 2.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
V1.0.0 - 10 January, 2026 - Initial Release
- Custom LINQ provider for JSON with 60+ LINQ methods
- Direct JSON processing without full deserialization
- Memory-efficient streaming for files larger than RAM
- Early termination support (10-20x faster for Take/First)
- .NET 10 async LINQ with async predicates
- Zero-allocation UTF-8 processing
- Basic JSONPath support for nested navigation