Introduction
CodecMapper is for cases where the wire contract should be written down on purpose instead of being inferred from CLR shape or serializer settings.
You author one Schema<'T> that describes the wire shape, then compile it into reusable codecs.
That schema is the important idea in the library:
- it is explicit
- it drives both encode and decode
- it is reusable across formats
- it keeps contract changes visible in code review
The core mental model
Most authored contracts follow one stable shape:
Schema.define<'T>
|> Schema.construct ctor
|> Schema.field ...
|> Schema.build
Read that pipeline from top to bottom:
Schema.define<'T>says which value the contract describesSchema.construct ctorsays how decode rebuilds the value- each
Schema.fieldmaps one wire field to one domain field Schema.buildfinishes the authored contract
Then you compile that schema into a codec for the format boundary you need:
let codec = Json.compile personSchema
let json = Json.serialize codec person
let decoded = Json.deserialize codec json
Why it feels different
CodecMapper is not trying to discover a contract from your record type.
Instead, the schema is the contract.
That makes it useful when:
- the wire shape matters and should stay reviewable
- JSON and XML should stay symmetric
- domain refinement should be explicit with
Schema.maporSchema.tryMap - AOT and Fable compatibility matter more than serializer magic
The first path to learn
Start with one simple progression:
- Getting Started
- How To Model A Basic Record
- How To Model A Nested Record
- How To Model A Validated Wrapper
Take the C# bridge, JSON Schema, and config-specific guides only after that core model feels natural.
CodecMapper