temporalio/sdk-dotnet

Temporal .NET SDK

C#

569

466 commits

updated Sep 30, 2026

See the code

README

Temporal .NET SDK

NuGet MIT

Temporal is a distributed, scalable, durable, and highly available orchestration engine used to execute asynchronous, long-running business logic in a scalable and resilient way.

This repository contains the Temporal .NET SDK, the framework for authoring workflows and activities using .NET programming languages, along with its extension packages.

To install and use the SDK, see the Temporalio package README. It covers the quick start, clients, workers, workflows, activities, Nexus, and testing.

Also see:


Contents

Packages

Each package has its own README next to its project, which is also its NuGet package page.

PackageDescription
TemporalioThe core SDK: clients, workers, workflows, activities, and Nexus operations
Temporalio.Extensions.Aws.LambdaRunning a worker inside an AWS Lambda invocation
Temporalio.Extensions.Aws.Lambda.OpenTelemetryOpenTelemetry helpers for workers running in AWS Lambda
Temporalio.Extensions.DiagnosticSourceSystem.Diagnostics.Metrics support for SDK metrics
Temporalio.Extensions.Gcp.CloudRun.IdClient identity derived from Google Cloud Run instance metadata
Temporalio.Extensions.Gcp.CloudRun.OpenTelemetryOpenTelemetry defaults for workers running on Google Cloud Run
Temporalio.Extensions.HostingClient dependency injection, activity dependency injection, and worker generic host support
Temporalio.Extensions.OpenTelemetryOpenTelemetry tracing support
Temporalio.Extensions.WorkflowStreamsExperimental durable, offset-based workflow publish/subscribe streams

Contributing

See CONTRIBUTING.md for how to open issues and pull requests, and the Development section below for building and testing this repository.

Development

Build

Prerequisites:

With all prerequisites in place, run:

dotnet build

Or for release:

dotnet build --configuration Release

The native Rust library is built automatically as part of the above, through the Cargo workspace at src/Temporalio/Bridge/Cargo.toml. That workspace exists so the library's dependency graph is pinned by a committed Cargo.lock; sdk-core is a published Rust library and deliberately does not commit one of its own. Its workspace tables and toolchain channel are mirrored from the submodule, so after bumping sdk-core copy over anything that changed upstream and then run:

mise run bridge:check-sync  # confirm the mirrored tables match the submodule
mise run bridge:relock      # refresh Bridge/Cargo.lock, then commit it

Code formatting

This project uses StyleCop analyzers with some overrides in .editorconfig. To format, run:

dotnet format

Can also run with --verify-no-changes to ensure it is formatted.

VisualStudio Code

When developing in vscode, the following JSON settings will enable StyleCop analyzers:

    "omnisharp.enableEditorConfigSupport": true,
    "omnisharp.enableRoslynAnalyzers": true

Testing

Run:

dotnet test

Can add options like:

  • --logger "console;verbosity=detailed" to show logs
  • --filter "FullyQualifiedName=Temporalio.Tests.Client.TemporalClientTests.ConnectAsync_Connection_Succeeds" to run a specific test
  • --blame-crash to do a host process dump on crash

To help debug native pieces and show full stdout/stderr, this is also available as an in-proc test program. Run:

dotnet run --project tests/Temporalio.Tests

Extra args can be added after --, e.g. -- -verbose would show verbose logs and -- --help would show other options. If the arguments are anything but --help, the current assembly is prepended to the args before sending to the xUnit runner.

Tests are eligible to run against Temporal Cloud unless they have a CloudTestExclusion attribute. Run or list the Cloud-eligible tests with:

dotnet test tests/Temporalio.Tests --filter "CloudTest!=Excluded"
dotnet test tests/Temporalio.Tests --list-tests --filter "CloudTest!=Excluded"

To inventory excluded tests, filter on CloudTest=Excluded, or filter on CloudTestExclusionReason to inspect a particular category.

The following environment variables can be set to override the environment:

  • TEMPORAL_TEST_CLIENT_TARGET_HOST - This must be set for any of the variables below to apply
  • TEMPORAL_TEST_CLIENT_NAMESPACE - Required if the above is set
  • TEMPORAL_TEST_CLIENT_CERT - Optional, must be present if below is
  • TEMPORAL_TEST_CLIENT_KEY - Optional, must be present if above is

Regenerating code

Every generator is a mise task. The .NET tools they need are pinned in .config/dotnet-tools.json and the rest in mise.toml. To regenerate everything the way CI does:

mise run gen

Or regenerate a single piece:

  • mise run gen:api - the Temporalio.Api.* protobuf types
  • mise run gen:nexus - the system Nexus workflow service bindings
  • mise run gen:interop - the bridge interop layer, from the sdk-core C header, using ClangSharpPInvokeGenerator

Each task installs the tools it needs on first run, so nothing has to be installed globally. Run mise tasks to see them all. Commit the regenerated output rather than hand-editing generated files; CI runs mise run gen and fails if it produces a diff.

gen:interop runs on Windows only, because the generator package ships native libclang binaries for Windows alone (it can be made to work on Linux, but it is annoying to set up). It is ordered last so the other generators still complete elsewhere.

If you cannot run a generator locally, let CI produce the output for you. The "Regen confirm unchanged" step uploads a generator-diff artifact holding a single generator.diff, a unified diff of everything the regen changed. From the repository root:

gh run download <run-id> -n generator-diff
git apply generator.diff

The artifact can also be downloaded as a zip from the Artifacts section of the workflow run page. Review the result and commit it as you would your own regen.

The Rust DLL itself is built automatically when the project is built, and needs protoc on the PATH (see Build).

Regenerating API docs

mise run docs

This builds the docs with docfx at the version pinned in .config/dotnet-tools.json.

c-sharp
dotnet
durable-execution
microservices
open-source
orchestration
temporal-sdk

Significant stargazers

Katelyn Gadd

497 followers · starred May 2023

Mohammad Ebrahimi

904 followers · starred Sep 2023

David Justo

96 followers · starred May 2023

Allan Ritchie

836 followers · starred May 2024

temporalio/sdk-dotnet

Temporal .NET SDK

C#

569

466 commits

updated Sep 30, 2026

See the code

README

Temporal .NET SDK

NuGet MIT

Temporal is a distributed, scalable, durable, and highly available orchestration engine used to execute asynchronous, long-running business logic in a scalable and resilient way.

This repository contains the Temporal .NET SDK, the framework for authoring workflows and activities using .NET programming languages, along with its extension packages.

To install and use the SDK, see the Temporalio package README. It covers the quick start, clients, workers, workflows, activities, Nexus, and testing.

Also see:


Contents

Packages

Each package has its own README next to its project, which is also its NuGet package page.

PackageDescription
TemporalioThe core SDK: clients, workers, workflows, activities, and Nexus operations
Temporalio.Extensions.Aws.LambdaRunning a worker inside an AWS Lambda invocation
Temporalio.Extensions.Aws.Lambda.OpenTelemetryOpenTelemetry helpers for workers running in AWS Lambda
Temporalio.Extensions.DiagnosticSourceSystem.Diagnostics.Metrics support for SDK metrics
Temporalio.Extensions.Gcp.CloudRun.IdClient identity derived from Google Cloud Run instance metadata
Temporalio.Extensions.Gcp.CloudRun.OpenTelemetryOpenTelemetry defaults for workers running on Google Cloud Run
Temporalio.Extensions.HostingClient dependency injection, activity dependency injection, and worker generic host support
Temporalio.Extensions.OpenTelemetryOpenTelemetry tracing support
Temporalio.Extensions.WorkflowStreamsExperimental durable, offset-based workflow publish/subscribe streams

Contributing

See CONTRIBUTING.md for how to open issues and pull requests, and the Development section below for building and testing this repository.

Development

Build

Prerequisites:

With all prerequisites in place, run:

dotnet build

Or for release:

dotnet build --configuration Release

The native Rust library is built automatically as part of the above, through the Cargo workspace at src/Temporalio/Bridge/Cargo.toml. That workspace exists so the library's dependency graph is pinned by a committed Cargo.lock; sdk-core is a published Rust library and deliberately does not commit one of its own. Its workspace tables and toolchain channel are mirrored from the submodule, so after bumping sdk-core copy over anything that changed upstream and then run:

mise run bridge:check-sync  # confirm the mirrored tables match the submodule
mise run bridge:relock      # refresh Bridge/Cargo.lock, then commit it

Code formatting

This project uses StyleCop analyzers with some overrides in .editorconfig. To format, run:

dotnet format

Can also run with --verify-no-changes to ensure it is formatted.

VisualStudio Code

When developing in vscode, the following JSON settings will enable StyleCop analyzers:

    "omnisharp.enableEditorConfigSupport": true,
    "omnisharp.enableRoslynAnalyzers": true

Testing

Run:

dotnet test

Can add options like:

  • --logger "console;verbosity=detailed" to show logs
  • --filter "FullyQualifiedName=Temporalio.Tests.Client.TemporalClientTests.ConnectAsync_Connection_Succeeds" to run a specific test
  • --blame-crash to do a host process dump on crash

To help debug native pieces and show full stdout/stderr, this is also available as an in-proc test program. Run:

dotnet run --project tests/Temporalio.Tests

Extra args can be added after --, e.g. -- -verbose would show verbose logs and -- --help would show other options. If the arguments are anything but --help, the current assembly is prepended to the args before sending to the xUnit runner.

Tests are eligible to run against Temporal Cloud unless they have a CloudTestExclusion attribute. Run or list the Cloud-eligible tests with:

dotnet test tests/Temporalio.Tests --filter "CloudTest!=Excluded"
dotnet test tests/Temporalio.Tests --list-tests --filter "CloudTest!=Excluded"

To inventory excluded tests, filter on CloudTest=Excluded, or filter on CloudTestExclusionReason to inspect a particular category.

The following environment variables can be set to override the environment:

  • TEMPORAL_TEST_CLIENT_TARGET_HOST - This must be set for any of the variables below to apply
  • TEMPORAL_TEST_CLIENT_NAMESPACE - Required if the above is set
  • TEMPORAL_TEST_CLIENT_CERT - Optional, must be present if below is
  • TEMPORAL_TEST_CLIENT_KEY - Optional, must be present if above is

Regenerating code

Every generator is a mise task. The .NET tools they need are pinned in .config/dotnet-tools.json and the rest in mise.toml. To regenerate everything the way CI does:

mise run gen

Or regenerate a single piece:

  • mise run gen:api - the Temporalio.Api.* protobuf types
  • mise run gen:nexus - the system Nexus workflow service bindings
  • mise run gen:interop - the bridge interop layer, from the sdk-core C header, using ClangSharpPInvokeGenerator

Each task installs the tools it needs on first run, so nothing has to be installed globally. Run mise tasks to see them all. Commit the regenerated output rather than hand-editing generated files; CI runs mise run gen and fails if it produces a diff.

gen:interop runs on Windows only, because the generator package ships native libclang binaries for Windows alone (it can be made to work on Linux, but it is annoying to set up). It is ordered last so the other generators still complete elsewhere.

If you cannot run a generator locally, let CI produce the output for you. The "Regen confirm unchanged" step uploads a generator-diff artifact holding a single generator.diff, a unified diff of everything the regen changed. From the repository root:

gh run download <run-id> -n generator-diff
git apply generator.diff

The artifact can also be downloaded as a zip from the Artifacts section of the workflow run page. Review the result and commit it as you would your own regen.

The Rust DLL itself is built automatically when the project is built, and needs protoc on the PATH (see Build).

Regenerating API docs

mise run docs

This builds the docs with docfx at the version pinned in .config/dotnet-tools.json.

c-sharp
dotnet
durable-execution
microservices
open-source
orchestration
temporal-sdk

Significant stargazers

Katelyn Gadd

497 followers · starred May 2023

Mohammad Ebrahimi

904 followers · starred Sep 2023

David Justo

96 followers · starred May 2023

Allan Ritchie

836 followers · starred May 2024

Languages

C#

100.0%