What’s new in Elsa 2.0

Sipke Schoorstra
C# Programming
Published in
7 min readMay 26, 2021


The Elsa 2.0 release is out, and it’s a big one!

This is the second release since Elsa 1.0 end of November 2019 and it contains many improvements and new features.

Let’s take a look.

What’s New

  1. Brand new designer with pan & zoom support and auto-layout
  2. Improved Workflow Builder API for Coded Workflows
  3. Coded Workflows visualization thanks to auto-layout
  4. Distributed Server / Multi Node support
  5. Elsa Server API Endpoints
  6. Clean separation between Elsa Server and Elsa Dashboard
  7. Composite Activities
  8. Activity Editors with Intellisense support powered by Monaco Editor
  9. Workflow Context Support
  10. New activities

1. Brand new designer with pan & zoom support and auto-layout

The designer has been completely rewritten from scratch, replacing JsPlumb with Dagre-D3 which offers better performance, easier to use API and built-in pan & zoom support.

Elsa’s new designer supports pan & zoom

2. Improved Workflow Builder API for Coded Workflows

The workflow builder API received significant improvements, the most important one being that you can now use C# lambdas for workflow expressions, rather than having to use JavaScript for dynamic expressions.

In addition, many activities now come with extension methods that make it even easier to write workflow classes.

For example, in Elsa 1 the HelloWorld workflow might look like this:

builder.StartWith<WriteLine>(x => x.TextExpression = new LiteralExpression("Hello World!"))

In Elsa 2, the same workflow looks like this:

builder.WriteLine("Hello World!");

And to write someone’s name, the workflow might look like this:

.WriteLine("Please enter you name:")
.WriteLine(context => $"Nice to meet you, {context.GetInput<string>()}!");

Notice that the second write line activity uses a C# lambda statement that dynamically sets the text to write based on the received input. In Elsa 1, you would have to resort to a JavaScript or Liquid expression. Which you can still do of course, and is some cases even more convenient such as when generating longer templated strings using Liquid syntax.

3. Coded Workflows visualization thanks to auto-layout

Thanks to the new designer implementation, it is now possible to display your coded workflows in the Elsa Dashboard.

For example, take the following workflow:

public class HeartbeatWorkflow : IWorkflow
private readonly IClock _clock;
public HeartbeatWorkflow(IClock clock) => _clock = clock;

public void Build(IWorkflowBuilder builder)
.WriteLine(() => $"Heartbeat at {_clock.GetCurrentInstant()}");

When you go to the Workflow Registry screen in the Elsa Dashboard, you will see this:

Coded workflows can now be visualized

4. Distributed Server / Multi Node support

A critical limitation with Elsa 1 was that it did not operate well in multi-node scenarios. Background timers would cause workflows to execute on all nodes, and there was no distributed locking in place to prevent concurrency conflicts when two nodes would update the same workflow instance.

In Elsa 2, workflows now operate smoothly across multiple nodes thanks to distributed locking & signaling.

You can learn more about this feature here.

5. Elsa Server API Endpoints

Elsa 2 exposes REST API endpoints that enable easy integration with external applications. It contains endpoints to manage workflow definitions as well as to trigger and signal workflows.

6. Clean separation between Elsa Server and Elsa Dashboard

The Elsa Server API Endpoints mentioned above allows for a clean separation between the Elsa Dashboard and Elsa Server.

This is in contrast to the Elsa 1 Dashboard MVC Area package where you had to register activities both with the server as well as the dashboard.

With Elsa 2, you register the available activities in the Startup class of your server app, and the Elsa Dashboard, which by the way is a simple SPA built with Stencil, will interact with the Elsa Server API to query the available activities.

7. Composite Activities

Composite Activities are a new class of custom activities that you can write using the Workflow Builder API.


public class AskNameActivity : CompositeActivity
public override void Build(ICompositeActivityBuilder builder)
.WriteLine("Hi there! Please tell me your name.")
.Then<Finish>(finish => finish.WithOutput(context =>context.GetInput<string>()));

These activities are like mini-workflows that you can add to your workflow.

A future update will enable you to create Composite Activities straight from the designer.

8. Activity Editors with Intellisense support powered by Monaco Editor

Activity Editors now use Monaco Editor for editing workflow expressions with support for JavaScript and Liquid.

This enables the use of intellisense, as seen in the following animation:

Elsa now comes with Intellisense support

Small caveat: intellisense requires types and functions to be registered explicitly, which hasn’t been done for every function as of yet. This is an ongoing effort.

9. Workflow Context Support

Elsa has a new concept called “Workflow Context”.

The idea here is that many workflows typically process some form of domain model that is persisted elsewhere (could be the same database or any other place).

Instead of having to write custom activities that load & persist these models, Elsa can now do this for you automatically.

All you have to do is implement a workflow context provider class and tell your workflow the .NET type of your model.

You can then configure the workflow when the context needs to be loaded. For example, do you want to load the object once before a “burst of execution” or before each and every activity executes? Or perhaps you want to control this on a per-activity basis? All you have to do is check some boxes.

You can learn more about this feature here.

10. New activities

Besides improving some of the existing activities, we added new ones as well, such as:

  • Azure Service Bus activities to send and receive messages using Azure Service Bus
  • Rebus activities to send and receive messages using Rebus
  • Blob storage activities to read, write and delete blobs from a configured storage provider using Storage.Net
  • Telnyx activities that integrate with the Telnyx APIs for telephony applications
  • Break activity that allows you to break out of a loop such as constructed with the For, ForEach and While activities
  • Switch activity that loosely models the C# switch construct
  • RunWorkflow activity, which allows you to execute a specific workflow by ID or name. You can execute a workflow in a “fire and forget” fashion or suspend workflow execution until the child workflow finishes.

What’s Fixed

  • Serialization issues have been fixed
  • Temporal activities such as Timer, Cron and StartAt now work reliably by relying on providers such as Quartz.NET and Hangfire
  • Workflow Execution Log is now stored separate from Workflow Instance
  • Many other issues too numerous to list here

For a full list of changes, fixes and improvements, checkout the Elsa 2.0 Milestone on GitHub.

Getting Started

To get started with Elsa 2, make sure to checkout the documentation website.

And if you just want to take it for a quick spin, run this Docker command:

docker run -t -i -e ELSA__SERVER__BASEURL='http://localhost:13000' -p 13000:80 elsaworkflows/elsa-dashboard-and-server:latest

Once the container is running, simply go to http://localhost:13000 and click around.


This release was made possible thanks to many contributors who generously donated their time and energy by testing out features, reporting issues and contributing code. A big Thank You to all of you guys. And of course to my GitHub Sponsors, I appreciate each and every one of you. It’s hard to think of a bigger compliment than sponsoring someone.

I am especially grateful to Interfirst, who have been with me on this journey to building out Elsa 2 from pretty much the very beginning when they decided that their platform should be powered by Elsa.

We released early versions of Elsa 2 into production early on, which immediately pretty much brought Elsa to her knees. But she got through it stronger and more resilient than ever being built on strong foundations that is ready for more to come.

I am proud to be part of this growing community that is warm and welcoming and to see folks helping one another out and I am excited about what comes next.

What’s Next

Going forward, we plan to release smaller, incremental updates. We are already collecting items for the Elsa 2.1 Milestone. The following types of additions may be expected from upcoming 2.x releases:


  • Testing & Debugging from within the Designer
  • Output Properties (similar to what we have in Windows Workflow Foundation)
  • Generic Task & Event activities
  • Webhooks (inbound + outbound)
  • Create custom activities from the Elsa Dashboard using JavaScript syntax
  • Multi-tenancy support
  • Open API activity provider & GraphQL activity provider
  • Secrets Store
  • Workflow DSL (to allow editing a text-based format of the workflow from the designer)

Besides that, we will keep improving the framework, APIs, activities, tooling and of course documentation.


For 3.0, we are rethinking parts of the workflow runtime by adding support for workflow scopes to allow for advanced activities such as Parrallel For Each and support for private variables that are local to the scope.

Additionally, I would like to revisit the processing of workflow instances by introducing workflow inboxes (similar to the Actor model) that will optimize overall workflow throughput.

There is a lot more on the backlog, and I am curious to hear about what you would like to see next!