ZeroAlloc.Mapping
1.6.13
dotnet add package ZeroAlloc.Mapping --version 1.6.13
NuGet\Install-Package ZeroAlloc.Mapping -Version 1.6.13
<PackageReference Include="ZeroAlloc.Mapping" Version="1.6.13" />
<PackageVersion Include="ZeroAlloc.Mapping" Version="1.6.13" />
<PackageReference Include="ZeroAlloc.Mapping" />
paket add ZeroAlloc.Mapping --version 1.6.13
#r "nuget: ZeroAlloc.Mapping, 1.6.13"
#:package ZeroAlloc.Mapping@1.6.13
#addin nuget:?package=ZeroAlloc.Mapping&version=1.6.13
#tool nuget:?package=ZeroAlloc.Mapping&version=1.6.13
ZeroAlloc.Mapping
Source-generated object mapper for .NET, an AutoMapper alternative that writes your mapping code at compile time: no reflection, no runtime configuration, NativeAOT-ready.
Why ZeroAlloc.Mapping
- Allocates what hand-written code allocates. A flat record copy allocates 72 B, the same as
new Dst(...)by hand. Update-in-place allocates 0 B, asserted by a test that fails CI on any regression. - 1.3× to 6.9× faster than AutoMapper on single-object mappings, measured in the same BenchmarkDotNet run.
- Works under NativeAOT and trimming. The generated body is plain property reads and a constructor call. The AOT smoke test publishes with trim and AOT warnings treated as errors.
- Mistakes fail the build, not the request. A destination property with no source is compile error ZAMP001, not a runtime exception on first use.
Install
dotnet add package ZeroAlloc.Mapping
The generator runs as part of dotnet build. There is no DI registration and no startup configuration.
Quick start
using ZeroAlloc.Mapping;
var order = OrderMappings.Map(new OrderRequest(42, "rush")); // a new Order
var orders = OrderMappings.Map(new List<OrderRequest> { new(1, "a"), new(2, "b") });
OrderMappings.Map(new OrderRequest(42, "gift wrap"), order); // update in place, 0 B
Console.WriteLine($"{order.Id}: {order.Notes}, {orders.Count} mapped");
public sealed record OrderRequest(int Id, string Notes);
public sealed class Order
{
public int Id { get; set; }
public string Notes { get; set; } = "";
}
[Map<OrderRequest, Order>]
public static partial class OrderMappings
{
public static partial void Map(OrderRequest src, Order existingDst);
}
One attribute gives you the single-object mapper and the List<T>, T[], IEnumerable<T> and IReadOnlyList<T> overloads. Declaring the partial void Map(src, existing) adds the update-in-place form. Each generated method is a null check and a direct constructor call or property writes.
What you get
- Constructor and property mapping with conversions, renames and per-property customisation.
- Fallible mapping:
[TryMap<,>]returnsResult<T, MappingError>instead of throwing, and a throwing smart constructor from ZeroAlloc.ValueObjects comes back as a failed result. - Flattening: map
Customer.Address.CityontoCitywith[MapProperty]. - Reverse mapping: one
[ReverseMap<,>]declaration gives you both directions. - Polymorphic dispatch: a compile-time type switch over derived types.
- Update in place for EF Core tracked entities and pooled objects.
- Collection overloads generated automatically, with an opt-out.
- Before and after hooks, which cost nothing when empty.
- Culture-aware parsing and strict or case-insensitive matching per mapper.
- IQueryable projection for EF Core, cycle-safe mapping for graphs with back-references, and deep clone.
- Integration: ZeroAlloc.Results powers the
Result<T, MappingError>path.
Performance
.NET 10, BenchmarkDotNet, same run. Allocations are exact; the last column is AutoMapper's time divided by ZeroAlloc.Mapping's.
| Scenario | ZeroAlloc.Mapping | AutoMapper | AutoMapper time |
|---|---|---|---|
| Update in place | 0 B | 0 B | 6.9× slower |
| Polymorphic dispatch | 32 B | 32 B | 5.7× slower |
| 1,000-item collection | 78.18 KB | 86.52 KB | 1.5× slower |
Mapperly, the other source-generated mapper, allocates within 0.1 KB of ZeroAlloc.Mapping in every scenario and runs at 0.95× to 1.21× its time. The performance page has all seven scenarios, the hand-written baseline, the per-call allocation budgets CI enforces, and how to reproduce the numbers.
Learn more
- Documentation site: mapping.zeroalloc.net
- Documentation source: guides, cookbook, the diagnostics reference and testing generated mappers.
- Related packages: ZeroAlloc.Results, ZeroAlloc.ValueObjects, ZeroAlloc.Validation.
- Changelog. Issues and pull requests are welcome on GitHub.
- MIT licensed. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- ZeroAlloc.Results (>= 1.2.4)
-
net8.0
- ZeroAlloc.Results (>= 1.2.4)
-
net9.0
- ZeroAlloc.Results (>= 1.2.4)
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 |
|---|---|---|
| 1.6.13 | 1,717 | 10/18/2026 |
| 1.6.12 | 334 | 10/16/2026 |
| 1.6.11 | 183 | 10/16/2026 |
| 1.6.10 | 368 | 10/15/2026 |
| 1.6.9 | 844 | 10/11/2026 |
| 1.6.8 | 1,074 | 9/30/2026 |
| 1.6.7 | 154 | 9/30/2026 |
| 1.6.6 | 540 | 9/28/2026 |
| 1.6.5 | 1,589 | 9/20/2026 |
| 1.6.4 | 127 | 9/20/2026 |
| 1.6.3 | 127 | 9/20/2026 |
| 1.6.2 | 146 | 9/19/2026 |
| 1.6.1 | 2,260 | 8/12/2026 |
| 1.6.0 | 3,370 | 5/24/2026 |
| 1.5.0 | 182 | 5/23/2026 |
| 1.4.1 | 473 | 5/12/2026 |
| 1.4.0 | 361 | 5/10/2026 |
| 1.3.1 | 260 | 5/9/2026 |
| 1.3.0 | 146 | 5/8/2026 |
| 1.2.0 | 143 | 5/8/2026 |