Table of Contents

Getting started

AvroSharp reads and writes Apache Avro™ data in .NET. This section starts with a first program, then covers the tasks most applications need, one page each. Every page's code is taken from a sample in samples/, which CI builds and runs, so it compiles and does what the page says.

Install

For the generic data model, schemas, container files and messages:

dotnet add package AvroSharp

For C# types generated from your .avsc files as the project builds (it brings in AvroSharp):

dotnet add package AvroSharp.Generators

The snappy, zstandard, bzip2 and xz codecs for container files are in AvroSharp.Codecs. The packages support .NET 8, 9 and 10, .NET Standard 2.0 and 2.1, and .NET Framework. The source generator needs the .NET 10 SDK or Visual Studio 2026 to build, and the code it generates runs on all of them.

A first program

An Avro schema is JSON. AvroSchema.Parse reads it into a RecordSchema here:

var userV1 = (RecordSchema)AvroSchema.Parse("""
    {"type":"record","name":"User","namespace":"example","fields":[
      {"name":"id","type":"int"},
      {"name":"name","type":"string"},
      {"name":"email","type":["null","string"],"default":null}]}
    """);

Without generated types, a record is a GenericRecord, whose fields are set by name. GenericDatumWriter writes it in Avro's binary encoding, and GenericDatumReader reads it back as an AvroValue:

var ada = new GenericRecord(userV1) { ["id"] = 1, ["name"] = "Ada", ["email"] = "ada@example.com" };
byte[] bytes = GenericDatumWriter.Create(userV1).WriteToArray(ada);
GenericRecord copy = GenericDatumReader.Create(userV1).Read(bytes).AsRecord();

Create returns a reader or writer cached for the schema. They are thread-safe, so an application keeps one per schema and shares it.

Data written with one version of a schema can be read as another. Here version 2 widens id, drops email and adds active with a default:

GenericRecord upgraded = GenericDatumReader.Create(writerSchema: userV1, readerSchema: userV2).Read(bytes).AsRecord();

Schema evolution explains the rules. A schema's fingerprint identifies it, for comparing schemas and in schema stores:

Console.WriteLine($"Fingerprint: 0x{userV1.Fingerprint64:X16}");

The whole program is the GettingStarted sample.

Next