Emerging architecture · Draft in places

Elsa
Foundation.

The modular architecture brain behind the next generation of Elsa Workflows.

Elsa Foundation decomposes the workflow engine into explicit domains, stable contracts, replaceable implementations, and sanctioned extension patterns — so Elsa can evolve without turning every package into a dependency magnet.

12+
Domains
.Core
Contracts
1
Artifact seam
Elsa.Workflows.DesignElsa.Workflows.RuntimeElsa.ActivitiesElsa.PersistenceElsa.ExpressionsElsa.SerializationElsa.LockingElsa.MessagingElsa.SchedulingElsa.ApiElsa.ModularityElsa.TasksElsa.Serverhost
§ The problem

What the refactor prevents

Seven shapes of accidental complexity that the Foundation refuses to allow.

God packages

One assembly knows everything.

Framework leakage

ASP.NET types in domain code.

Forced heavy dependencies

Pull EF Core to read a contract.

Infrastructure in contracts

.Core depends on a provider.

Inverted dependency direction

.Core references implementations.

Silent DI conflicts

Last-registered-wins surprises.

Names that hide meaning

Generic 'Service' / 'Manager' soup.

The Foundation does not eliminate complexity — it forces it into named, bounded places.

Before

Tangled package graph

After

Domains bounded by .Core
Design.CoreRuntime.CorePersistence.CoreSerialization.Core
§ The core idea

Every domain owns its contract

The same three-layer shape repeats for every feature in Elsa.

Layer 01
01

Domain / Feature Core

Contracts, models, value objects, events, exceptions, thin utilities.

e.g. Elsa.Workflows.Design.Core

Rule

No heavy dependencies.

Layer 02
02

Helper Libraries

Optional reusable implementations with focused dependencies.

e.g. Elsa.Tasks.Schedules

Rule

Never referenced by .Core.

Layer 03
03

Feature Implementation

DI registration and concrete services for a chosen technology.

e.g. Elsa.Serialization.Newtonsoft · Elsa.Locking.FileSystem

Rule

Implementations do not casually reference each other.

§ Domain map

The Elsa domain tree

Domains grouped by role. Hover a card to see its boundary.

Workflow Core

Elsa.Workflows.Design

Contract

Authored workflow definitions: drafts, versions, validation, design-time persistence.

Design.Core · Design.Validation · Design.Persistence

Elsa.Workflows.Runtime

Contract

Executes workflow artifacts, instances, bookmarks, logs, runtime state.

Runtime.Core · Runtime.Bookmarks · Runtime.Logs

Platform Services

Elsa.Persistence

Contract

Storage commands and read-side abstractions.

Persistence.Core · Persistence.EFCore

Elsa.Locking

Provider

Distributed locks behind a single contract.

Locking.Core · Locking.FileSystem · Locking.Redis

Elsa.Serialization

Provider

Pluggable serialization surface.

Serialization.Core · Serialization.Newtonsoft · Serialization.SystemText

Elsa.Expressions

Contract

Expression languages and evaluation contracts.

Expressions.Core · Expressions.Liquid · Expressions.JavaScript

Elsa.Messaging

Provider

Outbound and inbound message integrations.

Messaging.Core · Messaging.MassTransit

Elsa.Scheduling

Provider

Time-based triggers and scheduled work.

Scheduling.Core · Scheduling.Quartz

Elsa.Tasks

Helper

Background tasks and schedule helpers.

Tasks.Core · Tasks.Schedules

Composition & Surface

Elsa.Modularity

Host-facing

Feature composition: registration, options, ordering.

Modularity.Core · Modularity.Features

Elsa.Api

Host-facing

HTTP-shaped surface for design and runtime endpoints.

Api.Core · Api.Endpoints

Elsa.Http

Helper

HTTP-related activities and runtime integrations.

Http.Core · Http.Activities

Elsa.Notifications

Contract

In-process pub/sub plus delivery strategies.

Notifications.Core

§ The load-bearing split

Design and Runtime are separate bounded contexts

Design owns authoring. Runtime owns execution. Runtime must not depend directly on Design.

DESIGNRUNTIMEWorkflowDefinitionStateauthored sourceRead Models / Projectionsderived viewsWorkflowExecutablethe artifact (seam)Runtime Executioninstances · bookmarks · logs

Elsa.Workflows.Design

Drafts, versions, input/output definitions, activity trees, expression bindings, validation, layouts, design-time persistence.

Elsa.Workflows.Runtime

Executable artifacts, workflow instances, runtime state, bookmarks, logs, runtime integrations.

Design produces. Runtime executes. The artifact is the seam.
§ Runtime contract

Runtime contract first

Two invariants describe everything the runtime is allowed to know about.

Invariant 01

Executable-always-runs

If an artifact is published as runnable, the runtime must be able to load and execute it. Missing runtime types, registry drift, or module misconfiguration are bugs — not business gates.

Invariant 02

Artifact-only runtime

Runtime depends on the runnable artifact and configured runtime features. Never on drafts, designer metadata, authoring history, or design persistence.

DESIGNRUNTIMEdraftsdesigner metahistoryWorkflowExecutablesealed artifactexecute
§ Runtime execution model · emerging

Runtime as an actor system

Elsa's runtime is moving from a broad in-memory execution object model toward isolated, addressable execution actors — each with its own identity, mailbox, state boundary, and checkpoint behavior. This is the emerging Elsa 4 execution model, not a ratified constitution rule.

Provisional · conceptual actors, not concrete class names
Elsa runtime actor systemWorkflowExecutableartifact(pinned snapshot)Persistedruntime statecheckpointsdurable valuesbookmarksincidentsStartWorkflowPost-commit outboxActivityExecutionScheduleActivitySchedulerActivityCompletedBookmarkResumeBookmarkDurableValueCaptureDurableValueIncidentRecordIncidentCheckpointCommitCheckpointWorkflowExecutionactor · mailboxCommitCheckpointCreateBookmark

One execution, one durable identity.

Messages cross boundaries; state does not leak.

Runtime resumes from checkpoints, not from design documents.

Concurrency is explicit instead of accidental.

Conceptual actors

lifecycle owner

Workflow execution actor

Owns one workflow execution: start, run, suspend, resume, complete, fault, cancel. Pinned to one executable artifact snapshot for its entire lifetime.

per-node execution

Activity execution actor

One concrete execution of one executable node, with a durable identity distinct from the authored activity id. Survives loops, parallel branches, retries, and nested workflows.

pending & delayed work

Scheduler actor

Owns pending work, delayed work, branch and iteration scheduling, and resumable continuations.

external resume targets

Bookmark / stimulus actor

Resolves external stimuli into durable resume targets. Bookmarks point to stable resume target ids inside the pinned artifact — never to C# callback method names.

intentional state

Durable value boundary

Variables, workflow inputs and outputs, captured activity outputs, and external references are persisted on purpose. History is not runtime continuation state.

operational concerns

Incident & recovery actors

Faults, retries, leases, heartbeats, drain markers, and interrupted executions become explicit operational concepts rather than hidden side effects.

What it unlocks

Safer parallel execution

Cleaner suspension & resume

Better horizontal scaling

Inspectable runtime state

Deterministic snapshot pinning

Recovery without replaying authoring models

§ Extension model

Extend without coupling

Two axes describe every legitimate extension in Elsa.

Override

One implementation wins.

Replace a default implementation of a .Core contract — bring your own distributed lock provider or persistence commands.

.Coreimpl 1impl 2impl 3only one is registered
Extend

Many contributions, one aggregator.

Add implementations alongside built-ins. A single owner-owned aggregator runs all contributions — validators, sources, contributors, processors, handlers.

aggregatorall contributions run
Sanctioned patterns
Feature inheritanceEventsContribution interfacesReplacement contractsStartup tasksAdapter / BridgeProvider module decompositionCore-to-Core contractsApplication-level composition
§ Events & contributions

One event concept, explicit delivery strategy

Contribution flows use a single aggregating handler — not scattered anonymous dispatch.

Publisher
raises
IEvent
one concept
Strategy
sequential · parallel · background
Handlers / Contributors
aggregated
Result
single response
§ Catalogs

Catalogs replace live guessing

If an activity appears in the picker, it has a persisted catalog entry.

CLR modulesJSON definitionsWorkflow definitionsReconciliationtrusted sources → catalogActivity Catalogpersisted source of truthPicker/ API

Visibility is structural: catalog presence first, context filtering later.

§ Provider modules

Providers are siblings, not leaks

The .Core package exposes the contract. Provider packages opt into concrete technology.

Elsa.*.CorecontractElsa.Serialization.NewtonsoftproviderElsa.Serialization.SystemTextproviderElsa.Locking.FileSystemproviderElsa.Scheduling.QuartzproviderElsa.Messaging.MassTransitprovider
§ Elsa 3 compatibility

Compatibility through import

Import-only. No dual-run, no round-tripping, no Elsa-3-shaped runtime surface.

Elsa 3 definition
legacy asset
Import Adapter
one-shot map
Elsa 4 entities
native models
Elsa 4 runtime
executes natively
§ Impact

Why this matters

The Foundation is judged by what it makes possible for three audiences.

For users

  • Smaller dependency surfaces
  • Clearer deployment shapes
  • Design-only, runtime-only, and combined hosts
  • Replaceable infrastructure
  • More predictable upgrades

For contributors

  • Obvious ownership boundaries
  • Cataloged extension points
  • Less accidental coupling
  • Safer refactoring

For Elsa itself

  • Modular evolution
  • Provider ecosystem growth
  • Runtime hot-loading via Nuplane where appropriate
  • Architecture verifiable with maps and tests
§ Coda

A workflow engine made of explicit parts.

Elsa Foundation turns the workflow engine from a single gravitational center into a composed system of domains, contracts, providers, catalogs, and bridges. The result is an architecture that can grow without hiding its dependencies.

Elsa.ServerhostModularity · Nuplane composition.Workflows.Design.Coreimpl.Workflows.Runtime.Coreimpl.Persistence.Coreimpl.Locking.Coreimpl.Serialization.CoreimplWorkflowExecutableDesignRuntime
Status — draft in places · subject to refinement

Elsa Foundation · transitional architecture brain for Elsa Workflows