Juner.Sequence 1.0.0

dotnet add package Juner.Sequence --version 1.0.0
                    
NuGet\Install-Package Juner.Sequence -Version 1.0.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="Juner.Sequence" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Juner.Sequence" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Juner.Sequence" />
                    
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 Juner.Sequence --version 1.0.0
                    
#r "nuget: Juner.Sequence, 1.0.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 Juner.Sequence@1.0.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=Juner.Sequence&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Juner.Sequence&version=1.0.0
                    
Install as a Cake Tool

Juner.Sequence

High​‑performance, AOT-friendly streaming serializer for record-oriented JSON formats in .NET.

Record-oriented formats represent a sequence of independent JSON values, rather than a single JSON array.

Juner.Sequence provides zero‑allocation, fully streaming serialization and deserialization for record‑oriented JSON formats, including:

  • NDJSON (application/x-ndjson)
  • JSON Lines (application/jsonl)
  • JSON Text Sequences (RFC 7464, application/json-seq)

Built on top of System.Text.Json and System.IO.Pipelines, designed for:

  • 🚀 High performance (minimal allocations)
  • 🔒 AOT compatibility (JsonTypeInfo<T>‑based)
  • 🔄 True streaming via IAsyncEnumerable<T>
  • 🧱 Clean, layered architecture

Installation

dotnet add package Juner.Sequence

Quick Start

JsonSerializerContext (AOT‑safe)

[JsonSerializable(typeof(MyType))]
public partial class MyJsonContext : JsonSerializerContext { }

Serialize (NDJSON / JSON Lines)

// Serialize 
await SequenceSerializer.SerializeAsync(
    writer,
    source,
    MyJsonContext.Default.MyType,
    SequenceSerializerOptions.JsonLines,
    cancellationToken);

Deserialize (streaming)

await foreach (var item in SequenceSerializer.DeserializeAsyncEnumerable(
    reader,
    MyJsonContext.Default.MyType,
    SequenceSerializerOptions.JsonLines,
    cancellationToken))
{
    Console.WriteLine(item);
}

AOT‑Friendly Design

Juner.Sequence is built around:

JsonTypeInfo<T>

instead of JsonSerializerOptions.

Why?

  • No runtime reflection
  • Native AOT compatible
  • Faster and more predictable metadata generation

Runtime Behavior

.NET 9 or later

SequenceSerializer writes directly to PipeWriter using JsonSerializer.SerializeAsync, providing the fastest possible path.

.NET 8 or earlier

Serialization falls back to a stream‑based implementation:

writer.AsStream()

This ensures compatibility, though it may introduce additional allocations compared to the PipeWriter-based fast path.


SequenceSerializerOptions

SequenceSerializerOptions defines how records are framed during serialization and deserialization.

Built‑in presets

Name Description
JsonSequence RFC 7464 (RS + JSON + LF)
JsonLines NDJSON / JSON Lines ( JSON + LF)

Invalid Options

A valid sequence format must define at least one start or end delimiter.
Options that define no framing are considered invalid and are not supported.

The library contains an internal default value used only for initialization,
but it is not available for public use.


FlushStrategy

Controls how flushing is performed during serialization.

Strategy Behavior
None Caller or transport controls flushing
PerRecord Flush after each record (default)

PerRecord improves real‑time behavior but reduces throughput.

PerRecord is useful for real-time streaming scenarios (e.g. logs, HTTP streaming), while None maximizes throughput in batch processing.


Framing Engine (Core Feature)

The deserializer uses optimized fast‑paths for common formats:

  • NDJSON / JSON Lines
    (Start = empty, End = 1 byte)

  • JSON Sequence
    (Start = 1 byte, End = 1 byte)

For custom formats, it falls back to a general delimiter‑matching engine that supports:

  • Multiple start delimiters
  • Multiple end delimiters
  • Variable‑length delimiters
  • Longest‑match semantics

The final frame is handled separately, with optional support for ignoring incomplete frames.


Optional Extensions

JsonTypeInfo (non‑generic) Extensions — advanced use only

These extensions allow passing a non‑generic JsonTypeInfo:

using Juner.Sequence.Extensions;

await SequenceSerializer.SerializeAsync(
    writer,
    source,
    (JsonTypeInfo)myTypeInfo,
    SequenceSerializerOptions.JsonLines);

⚠️ Not recommended for general use.
Not AOT‑safe and will throw if the provided JsonTypeInfo does not match T.


JsonSerializerOptions Support — not guaranteed AOT‑safe

These extensions resolve metadata via JsonSerializerOptions.TypeInfoResolver:

using Juner.Sequence.Extensions.Json;

await SequenceSerializer.SerializeAsync(
    writer,
    source,
    jsonSerializerOptions,
    SequenceSerializerOptions.JsonLines);

⚠️ May rely on reflection and is not guaranteed to be AOT‑safe.


JsonSerializerOptions.Default Support — explicitly not AOT‑safe

Convenience APIs using JsonSerializerOptions.Default:

using Juner.Sequence.Extensions.Json;

await SequenceSerializer.SerializeAsync(
    writer,
    source,
    SequenceSerializerOptions.JsonLines);

These APIs are annotated with:

  • RequiresUnreferencedCode
  • RequiresDynamicCode

⚠️ Explicitly not AOT‑safe.


Encoding Support (AOT‑safe)

Supports non‑UTF‑8 encodings via transcoding streams:

using Juner.Sequence.Extensions;

await SequenceSerializer.SerializeAsync(
    writer,
    source,
    typeInfo,
    SequenceSerializerOptions.JsonLines,
    Encoding.UTF32);

UTF‑8 uses the fast path with no overhead.


Stream‑based Extensions (AOT‑safe)

Convenience APIs for working directly with Stream:

using Juner.Sequence.Extensions;

await SequenceSerializer.SerializeAsync(
    stream,
    source,
    typeInfo,
    SequenceSerializerOptions.JsonLines);

Internally uses PipeReader.Create(stream) for deserialization.


Supported Formats

Format Content-Type Notes
NDJSON application/x-ndjson newline‑delimited
JSON Lines application/jsonl equivalent to NDJSON
JSON Sequence application/json-seq RFC 7464 (RS‑delimited)

About JSON Array (application/json)

JSON arrays are already well supported by JsonSerializer for stream-based scenarios.

Juner.Sequence is designed specifically for record-oriented streaming formats, where each JSON value can be processed independently.

For this reason, JSON arrays are intentionally not supported.


Architecture

graph TD;
    A[Juner.Sequence<br/>Core] --> B[Extensions<br/>Encoding Support];
    A --> C[Extensions.Json<br/>JsonSerializerOptions Support];
    A --> D[Extensions.JsonTypeInfo<br/>Advanced Scenarios];

When to Use

  • Processing large JSON streams
  • Building high‑performance pipelines
  • Targeting Native AOT
  • Working with PipeReader / PipeWriter

When NOT to Use

  • Small payloads → JsonSerializer is simpler
  • JSON arrays → use JsonSerializer
  • Native AOT scenarios → avoid JsonSerializerOptions.Default (not AOT‑safe)

License

MIT

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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 (2)

Showing the top 2 NuGet packages that depend on Juner.Sequence:

Package Downloads
Juner.AspNetCore.Sequence

Streaming JSON support for ASP.NET Core (NDJSON, JSON Lines, JSON Sequence). Also supports JSON arrays as non-streaming input/output for convenience. Provides Minimal API and MVC integration with content negotiation and OpenAPI support.

Juner.Http.Sequence

Streaming JSON sequence support for HttpClient and HttpContent. Send and receive NDJSON, JSON Lines, and JSON Sequence using IAsyncEnumerable<T>. Built on System.Text.Json and the Juner.Sequence core serializer.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 110 3/30/2026
1.0.0-preview-2 104 3/26/2026