CodecMapper 0.3.0

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

CodecMapper

CI NuGet Docs License

CodecMapper is a schema-first serialization library for F# with native AOT and Fable compatibility.

It lets you define one schema and compile it into multiple codecs. The same mapping drives both encode and decode, so JSON and XML stay symmetric.

It's for cases where the wire contract should be explicit, reviewable, and reusable instead of being inferred from CLR shape or serializer settings.

The idea

You author one Schema<'T> that describes the wire shape:

open CodecMapper
open CodecMapper.Schema

type Person = { Id: int; Name: string }
let makePerson id name = { Id = id; Name = name }

let personSchema =
    define<Person>
    |> construct makePerson
    |> field "id" _.Id
    |> field "name" _.Name
    |> build

Then you compile that schema into a reusable codec:

let codec = Json.compile personSchema

let person = { Id = 1; Name = "Ada" }
let json = Json.serialize codec person
let decoded = Json.deserialize codec json

That is the core model of the library:

  • the schema is the contract
  • encode and decode come from the same definition
  • contract changes stay visible in one place

That same authored path also covers explicit tagged unions, string-valued enums, message envelopes, and recursive case trees through Schema.union, Schema.inlineUnion, Schema.envelope, Schema.stringEnum, and Schema.delay.

Why use it

CodecMapper fits when:

  • you want the wire contract to be authored explicitly
  • JSON and XML should stay symmetric
  • domain refinement should be explicit with Schema.map or Schema.tryMap
  • Native AOT and Fable compatibility matter

It is not trying to replace convention-based serializers for every use case.

Formats and scope

The same authored schema can compile into:

  • JSON codecs
  • XML codecs
  • config-oriented YAML codecs
  • flat KeyValue projections

Authored tagged unions stay on that same contract path instead of switching to a separate codegen or reflection model.

The core library stays focused on explicit schemas and handwritten runtimes. The separate bridge assembly exists for .NET interoperability with existing C# serializer contracts.

Start here

Use these after the core authored path is clear:

Compatibility

CodecMapper is designed to stay usable from Native AOT and Fable-oriented targets. CI includes both in-repo compatibility sentinels and packaged-consumer Fable checks.

Performance Status

Current status is mixed but clear:

  • CodecMapper is competitive on small messages and medium nested-record workloads.
  • System.Text.Json still leads on string-heavy and numeric-heavy payloads.
  • Newtonsoft.Json trails both across the current manual scenario matrix.

The project ships both a manual scenario runner and a repeatable perf workflow for hot-path investigation:

Latest local manual snapshot, measured on March 16, 2026:

Scenario CodecMapper serialize STJ serialize CodecMapper deserialize STJ deserialize Takeaway
small-message 519.5 ns 676.9 ns 990.1 ns 928.4 ns CodecMapper still wins tiny-message serialize; STJ keeps a slight decode lead.
person-batch-25 8.83 us 8.36 us 26.08 us 20.41 us Medium nested serialize stays close, but decode is not yet even.
person-batch-250 86.93 us 78.18 us 247.16 us 190.27 us Larger nested batches remain competitive on serialize, while STJ leads decode throughput.
escaped-articles-20 46.00 us 33.87 us 80.78 us 63.08 us String-heavy payloads are still a clear weak spot.
telemetry-500 393.93 us 311.45 us 745.63 us 520.84 us Numeric-heavy flat payloads still need significant optimization work, especially on decode.
person-batch-25-unknown-fields 7.92 us 7.51 us 30.50 us 24.23 us Unknown-field decode improved, but STJ still holds a noticeable lead.

Those numbers are machine-specific. Compare ratios and workload shape more than the absolute values.

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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 92 3/16/2026
0.2.0 87 3/15/2026
0.1.0 85 3/11/2026

Added authored tagged unions and recursive unions across JSON, XML, YAML, and KeyValue; JSON Schema export for tagged unions and string enums; inline union, string enum, and message envelope helpers; refreshed docs, compatibility coverage, and benchmark snapshots.