Cosmigrator 1.0.4

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

Cosmigrator

A migration framework for Azure Cosmos DB. Version-controlled, reversible schema changes for your NoSQL documents.

CI/CD NuGet Downloads codecov License: MIT

What it does

Cosmigrator manages document schema changes in Cosmos DB the same way EF Core migrations handle relational databases — except it's built for NoSQL. Write C# migration classes, run them forward or roll them back from the CLI.

Supports .NET 8, .NET 9, and .NET 10.

Install

dotnet add package Cosmigrator

Quick start

1. Create a console app

dotnet new console -n MyService.Migrations
cd MyService.Migrations
dotnet add package Cosmigrator

2. Add appsettings.json

{
  "CosmosDb": {
    "ConnectionString": "AccountEndpoint=https://your-account.documents.azure.com:443/;AccountKey=your-key",
    "DatabaseName": "MyDatabase"
  }
}

3. Write Program.cs

One line. MigrationHost.RunAsync handles host building, Serilog setup, Cosmos client creation, and CLI parsing.

using System.Reflection;
using Cosmigrator;

await MigrationHost.RunAsync(args, Assembly.GetExecutingAssembly());

4. Add a migration

Create a Migrations/ folder and add your first migration:

using System.Text.Json.Nodes;
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.Logging;

public class _20250219_000001_AddEmailToUsers : IMigration
{
    public string Id => "20250219_000001";
    public string Name => "AddEmailToUsers";
    public string ContainerName => "Users";
    public object? DefaultValue => "";

    public async Task UpAsync(Container container, CosmosClient client)
    {
        using var loggerFactory = LoggerFactory.Create(b => b.AddConsole());
        var helper = new BulkOperationHelper(loggerFactory.CreateLogger<BulkOperationHelper>());

        var docs = await helper.ReadAllDocumentsAsync(container);
        var toUpdate = docs.Where(d => d["email"] == null).ToList();

        foreach (var doc in toUpdate)
            doc["email"] = JsonValue.Create(DefaultValue);

        if (toUpdate.Count > 0)
            await helper.BulkUpsertAsync(container, toUpdate);
    }

    public async Task DownAsync(Container container, CosmosClient client)
    {
        using var loggerFactory = LoggerFactory.Create(b => b.AddConsole());
        var helper = new BulkOperationHelper(loggerFactory.CreateLogger<BulkOperationHelper>());

        var docs = await helper.ReadAllDocumentsAsync(container);

        foreach (var doc in docs)
            doc.Remove("email");

        await helper.BulkUpsertAsync(container, docs);
    }
}

5. Run it

dotnet run                           # Apply all pending migrations
dotnet run -- rollback               # Undo the last migration
dotnet run -- rollback --steps 3     # Undo the last 3
dotnet run -- status                 # Show applied vs pending
dotnet run -- list                   # Show all discovered migrations

Prerequisites

Cosmigrator does not create containers automatically. You must provision them yourself (Terraform, Bicep, Azure Portal, etc.) before running migrations.

Container Partition Key Purpose
__MigrationHistory /id Tracks applied migrations
Your target containers Per your schema Where migrations operate

The IMigration interface

Every migration implements this interface:

public interface IMigration
{
    string Id { get; }              // "20250219_000001" — used for ordering
    string Name { get; }            // Human-readable description
    string ContainerName { get; }   // Target container
    object? DefaultValue => null;   // Optional default for property additions

    Task UpAsync(Container container, CosmosClient client);
    Task DownAsync(Container container, CosmosClient client);
}

Migrations are discovered automatically via reflection and executed in Id order.

Migration scenarios

The sample project includes working examples for common patterns:

Migration What it does
AddAgePropertyToUsers Adds a property with a default value to all documents
RemoveMiddleNameProperty Removes a property from all documents
RenameUserNameToDisplayName Renames a property while preserving data
AddUniqueKeyPolicyToOrders Changes unique key policy by recreating the container
AddCompositeIndexToUsers Adds a composite index to the indexing policy

Advanced: custom host setup

If you need control over configuration and logging, use the overload that accepts IConfiguration and ILoggerFactory:

using System.Reflection;
using Cosmigrator;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();

var host = Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((_, config) =>
    {
        config
            .SetBasePath(AppContext.BaseDirectory)
            .AddJsonFile("appsettings.json", optional: false)
            .AddEnvironmentVariables()
            .AddCommandLine(args);
    })
    .UseSerilog((ctx, cfg) => cfg.ReadFrom.Configuration(ctx.Configuration))
    .Build();

var loggerFactory = host.Services.GetRequiredService<ILoggerFactory>();
var configuration = host.Services.GetRequiredService<IConfiguration>();

await MigrationHost.RunAsync(configuration, loggerFactory, args, Assembly.GetExecutingAssembly());

This is useful when you want to:

  • Customize Serilog sinks (Seq, Application Insights, etc.)
  • Add environment-specific configuration
  • Integrate with an existing host pipeline

Deployment

Cosmigrator exits with code 0 on success and 1 on failure. This makes it easy to use as:

  • A Kubernetes init container — block the main pod until migrations pass
  • A CI/CD pipeline step — fail the deployment if a migration fails
  • A Docker Compose dependency — run before your app starts
# Example: Kubernetes init container
initContainers:
  - name: migrations
    image: myregistry/myservice-migrations:latest
    command: ["dotnet", "MyService.Migrations.dll"]

Project structure

src/Cosmigrator/              Core library (the NuGet package)
samples/Cosmigrator.Sample/   Example console app with 5 migration scenarios
tests/Cosmigrator.Tests/      Unit tests (xUnit + FluentAssertions)

Contributing

Contributions welcome. Please read CONTRIBUTING.md before opening a PR.

git clone https://github.com/AdelSS04/Cosmigrator.git
cd Cosmigrator
dotnet build
dotnet test

License

MIT

Product 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. 
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
1.0.4 88 2/20/2026
1.0.3 82 2/19/2026
1.0.0 98 2/19/2026

See CHANGELOG.md for release notes