mbraceproject/FsPickler
53.9
Weak · 23 September 2026
8.5k
lines of production code
F#
primary language
5
measurements over time
What this system is
FsPickler is a high-performance serialization and cloning library for .NET, supporting binary, XML, JSON, and BSON formats. It provides a modular, composable API for serializing complex F\# and C\# types, including recursive structures and generic collections. The system features dynamic IL generation for optimized performance and includes utilities for object graph traversal, memory estimation, and shallow copying. It is designed for cross-platform compatibility via .NET Standard 2.0 and includes comprehensive testing and benchmarking suites.
Features
Add BSON serialization support and refactor JSON handling
The FsPickler.Json library now includes support for the BSON (Binary JSON) serialization format, implemented in new files such as BsonFormat.fs and Combinators.fs. The existing JSON serialization logic has been refactored to support custom top-level sequence separators, allowing for more flexible data structures. Additionally, the implementation includes a fix for a bug in Json.NET 8 where enabling SupportMultipleContent caused issues, and the code now handles DateTime and DateTimeOffset serialization with improved accuracy for BSON formats.
src/FsPickler.Json · high confidence
Added utility modules for C\# interop, IL emission, hashing, reflection, and shallow copying
The FsPickler library added several new internal utility modules to support serialization improvements. CsharpProxy.fs provides extension methods to convert C\# Func/Action delegates to F\# functions, enabling easier interop with C\#-generated types. Emit.fs introduces a dynamic IL generation system for creating cached dynamic methods, which is used by ShallowCopy.fs to perform fast, compiled shallow copies of objects. Hashing.fs implements FNV-1a and MurMur3 hash stream factories for computing object hashes. Reflection.fs adds helpers for member gathering, supertype resolution, and recursive type detection. TypeShapeExtensions.fs provides visitor interfaces for System.Tuple and F\# Choice types. Utils.fs adds general-purpose helpers like null-checking, exception handling, and stream utilities. These changes collectively enhance the library's ability to serialize complex types, including C\# compiler-generated types and LINQ enumerables, while improving performance through compiled IL and caching.
src/FsPickler/Utils · high confidence
New pickler generation components for serialization, caching, and code emission
The FsPickler serialization engine has been restructured into a new set of internal modules within the PicklerGeneration folder. CustomPickler.fs introduces support for types with static factory methods and a 'CloneableOnly' mode for non-serializable types. DataContractPickler.fs provides serialization for types using DataMember and serialization callback attributes. FSharpTypeGen.fs handles F\# union types. FieldPicklers.fs manages serialization for struct and class fields. ISerializablePickler.fs implements the ISerializable interface. PicklerCache.fs provides a thread-safe singleton cache for generated picklers. PicklerEmit.fs contains the IL emission logic for serialization, deserialization, cloning, and visiting. PicklerGenerator.fs routes type shapes to their corresponding pickler implementations. PicklerRegistry.fs defines the interface and implementation for registering custom picklers and declaring types as serializable.
src/FsPickler/PicklerGeneration · high confidence
Architecture
Repository infrastructure and build system modernization
The repository was restructured to support modern .NET development workflows. A new Directory.Build.props file centralizes NuGet metadata and build properties, while the solution file (FsPickler.sln) was regenerated to reflect the new project structure. Build automation was updated to use FAKE 5 with .NET Core/SDK 3.1, replacing older build scripts. Additionally, the project migrated to Paket for package management and introduced a Dockerfile and .dockerignore to support containerized builds and CI/CD pipelines.
(repo-wide) · high confidence
Behavioural changes
Migrate FsPickler to MBrace namespace and add test script
The FsPickler library has been migrated from the Nessos namespace to the MBrace namespace, reflecting a broader rebranding or organizational shift. As part of this migration, a new F\# script (Test.fsx) has been added to demonstrate usage of the updated API, including binary and XML pickling of quotations and functions. Additionally, the project's paket.references file has been updated to include dependencies on TypeShape, FSharp.Core, System.Reflection.Emit.Lightweight, and Microsoft.SourceLink.GitHub.
src/FsPickler · high confidence
Refactored FsPickler serialization architecture and API
The FsPickler library has been refactored to introduce a new \BinarySerializer\ and \TextSerializer\ base classes, separating binary and text-based serialization logic. This change introduces a \Pickle\<'T\>\ type for type-annotated pickles, adds \PickleTyped\ and \UnPickleTyped\ extension methods, and exposes \FsPickler.CreateBinarySerializer\ and \CreateXmlSerializer\ for explicit serializer creation. Additionally, the library now supports object graph sifting via \FsPickler.Sift\ and \UnSift\, provides an \ObjectSizeCounter\ for memory estimation, and adds a \VisitObject\ method for graph traversal. The \Pickler\ module now includes combinators for sequences, tuples, and custom serialization info, alongside utility methods like \ComputeSize\ and \ComputeHash\.
src/FsPickler/FsPickler · high confidence
Refactored core serialization architecture with new state and format abstractions
The serialization engine has been refactored to introduce new core abstractions: \IPickleFormat\ (split into \IPickleFormatWriter\ and \IPickleFormatReader\ interfaces) and new state classes (\WriteState\, \ReadState\, \CloneState\, \VisitState\) that encapsulate serialization context, caching, and visitor/sifter support. The \CompositePickler\ and \PrimitivePickler\ implementations have been updated to use these new states, enabling features like object sifting, cyclic object detection, and subtype resolution to be managed through the serialization context rather than individual picklers. This change also includes the addition of \ReflectionCache\ for managing type metadata and assembly loading, and updates the \Pickler\ base class to support the new \IsCloneableOnly\ and \UseWithSubtypes\ behaviors.
src/FsPickler/Pickler · high confidence
Rewrite collection and type pickler combinators
The FsPickler library has been refactored to use a new modular combinator architecture. The \src/FsPickler/Combinators\ directory now contains dedicated pickler implementations for arrays, collections (Set, Map, Dictionary), F\# types (Option, Choice, List, Tuple), sequences, and wrappers. This change introduces new internal types such as \ArrayPickler\, \FSharpSetPickler\, \FSharpMapPickler\, \ListPickler\, \OptionPickler\, \ChoicePickler\, \SeqPickler\, and \TuplePickler\ to handle serialization, cloning, and visiting for these specific data structures. The implementation leverages a \CompositePickler\ pattern to manage the serialization logic for each type, ensuring consistent handling of primitive arrays, recursive types, and sequence headers across different formats.
src/FsPickler/Combinators · high confidence
Updated serialization formats with new versioning and structural changes
The binary, XML, and size-counter format implementations have been rewritten to use a new internal versioning scheme (e.g., \formatv4000\), ensuring that serialized data includes updated headers and metadata. The binary format now records endianness and code page information in the serialization header, while the XML format has been adjusted to include version attributes and updated flag handling. These changes modify how data is read and written, which may affect compatibility with older serialized data or require updates to existing serialization pipelines.
src/FsPickler/Format · high confidence
Test coverage
Added FsPickler benchmark suite for serialization performance; Added comprehensive unit tests for serialization, cloning, and assembly loading.
Dependencies
Migrate to .NET Standard 2.0 and Paket for dependency management
The project has been updated to target .NET Standard 2.0 (alongside .NET 4.5), enabling broader cross-platform compatibility. The build system has been migrated from NuGet packages.config to Paket, with new paket.dependencies and paket.lock files defining explicit versions for libraries like FSharp.Core (4.3.2), TypeShape (8.0.0), and Newtonsoft.Json (10.0.1). This change also updates the test and benchmark projects to use .NET Core 3.1 and .NET 4.7.2, and introduces a 'Release-NoEmit' configuration for the main library.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 57 → 54 (-3.1)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 93 → 81 (-11.6)
- Architecture 100 → 100 (+0.0)
- Maturity 37 → 37 (+0.0)
- Readiness 55 → 49 (-5.5)
- Security 99 → 98 (-0.5)
Resolved (25)
- Dependency hygiene not measured — no packages were read
- Duplicated block (10 lines × 2) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (10 lines × 2) (src/FsPickler/Pickler/CompositePickler.fs)
- Duplicated block (13 lines × 2) (src/FsPickler/Combinators/Array.fs)
- Duplicated block (5 lines × 2) (src/FsPickler/Combinators/Collections.fs)
- Duplicated block (5 lines × 3) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (5 lines × 4) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (6 lines × 2) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (6 lines × 2) (src/FsPickler/Pickler/Pickler.fs)
- Duplicated block (6 lines × 3) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (6 lines × 3) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (7 lines × 2) (src/FsPickler/PicklerGeneration/FieldPicklers.fs)
- Duplicated block (7 lines × 2) (src/FsPickler/PicklerGeneration/FieldPicklers.fs)
- Duplicated block (7 lines × 2) (src/FsPickler/Utils/Utils.fs)
- Duplicated block (8 lines × 2) (src/FsPickler/PicklerGeneration/DataContractPickler.fs)
- Duplicated block (8 lines × 4) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (9 lines × 2) (src/FsPickler/PicklerGeneration/ISerializablePickler.fs)
- Duplicated block (9 lines × 3) (src/FsPickler/Combinators/Array.fs)
- Duplicated block (9 lines × 3) (src/FsPickler/Combinators/Array.fs)
- Duplicated block (9 lines × 3) (src/FsPickler/Combinators/Tuple.fs)
- …and 5 more
New (29)
- Documentation: contradicts the code (docs/content/benchmarks.md)
- Duplicated block (10–11 lines × 2) (src/FsPickler/Combinators/Array.fs)
- Duplicated block (12 lines × 2) (src/FsPickler/Pickler/CompositePickler.fs)
- Duplicated block (13 lines × 2) (src/FsPickler/Combinators/Array.fs)
- Duplicated block (5 lines × 2) (src/FsPickler/Pickler/Pickler.fs)
- Duplicated block (5 lines × 2) (src/FsPickler/PicklerGeneration/ISerializablePickler.fs)
- Duplicated block (5 lines × 3) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (5 lines × 4) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (6 lines × 2) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (6 lines × 4) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (6 lines × 4) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (7 lines × 2) (src/FsPickler/PicklerGeneration/DataContractPickler.fs)
- Duplicated block (7 lines × 3) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (7–8 lines × 2) (src/FsPickler/PicklerGeneration/DataContractPickler.fs)
- Duplicated block (7–8 lines × 2) (src/FsPickler/Utils/Hashing.fs)
- Duplicated block (8 lines × 2) (src/FsPickler/Combinators/Tuple.fs)
- Duplicated block (8–10 lines × 2) (src/FsPickler/PicklerGeneration/ISerializablePickler.fs)
- Duplicated block (9 lines × 3) (src/FsPickler/Combinators/Array.fs)
- Duplicated block (9–10 lines × 3) (src/FsPickler/Combinators/Array.fs)
- High IaC: WD-DOCKER-0013 (Dockerfile)
- …and 9 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
mbraceproject/FsPickler was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 0eb5ebfffb2b35919b5ca6e551d457b69843a0fb — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.