Thank you for your interest in contributing to Elsa.
We value clarity, discipline, and maintainability in our codebase. Well-scoped pull requests and high-quality bug reports help us maintain velocity without sacrificing quality.
Whether you're:
- Reporting a bug
- Proposing a feature
- Submitting a fix
- Improving documentation
- Becoming a maintainer
— your contributions are welcome.
Elsa follows Trunk Based Development.
All changes happen through Pull Requests targeting the main branch.
- Fork the repository and create your branch from
main. - If you've added code that should be tested, add tests.
- If you've changed APIs, update documentation.
- Ensure the test suite passes.
- Open a Pull Request.
Open new consolidated Core, Extensions, Studio, Apps and Templates issues and pull requests in elsa-core. Identify the affected product and version. Retained 3.8/3.9 maintenance continues through its existing source-repository procedure until an explicitly approved replacement is verified; consolidation does not end that support or move its publisher automatically.
The source cutoff records the accepted inputs and its actual-main activation condition. For existing donor contributions, consult the source contribution handoff and register. Reuse a matching Core continuation when one exists. When scheduling new continuation work, link the original issue/PR and preserve its author attribution; an open historical source item is not automatically an active Core task.
All five products share this repository. Core, Extensions, Studio and Apps build through root Elsa.sln. Templates has its independent templates/Elsa.Templates.slnx product solution and root Elsa.Templates.slnf; its entries in Elsa.sln are navigation only. Keep code, tests and documentation in the owning product's directories. Core, Extensions and Studio use src/, test/ and docs/; Apps uses src/, scripts/tests/ and docs/; Templates uses src/, test/ and docs/ within its product root. Shared build scripts, central package policy and solution filters remain at the repository root. Cross-product references use public contracts; moving a file does not change its package or activity identity.
Run commands from the repository root. Start with the owning project and test project, then use the relevant root filter or full solution when the change crosses boundaries:
dotnet build Elsa.Core.slnf
dotnet build Elsa.Extensions.slnf
dotnet build Elsa.Studio.slnf
dotnet build Elsa.Apps.slnf
dotnet build Elsa.Templates.slnf
dotnet test core/test/unit/Elsa.Workflows.Core.UnitTests/Elsa.Workflows.Core.UnitTests.csprojThe Core filter excludes the cross-product Elsa.Secrets.DefaultHost.IntegrationTests fixture; it remains in the full solution. These filters include required project references; they are development selections, not isolated package-consumer or publication proof. See Core, Extensions and Studio for product entrypoints, and the package proof for artifact checks. Studio browser bundles require the documented Node build before their .NET hosts.
Ordinary independent product releases must not bump or republish unrelated products. The dated first aligned 3.10 baseline and publisher-cutover ADR remains an operational handoff under #8741; it does not make every future product release lockstep. A directory move or successful local build does not authorize publication or source-repository archival. Keep existing source issue/PR attribution and link any reviewed adoption to its original contribution.
Apps is a released Elsa 3.9.0 package consumer with nine net10.0 projects, its own scoped package policy and no Core NuGet package outputs. See Apps for local build/image commands and the source import register for original contributions. The imported source publisher remains inert; the new Apps workflow validates local images without registry writes. Existing source publication and retirement ownership remain separate.
Templates retains the independent Elsa.Templates 3.9.0 pack identity and version, outside root NUKE/global packing. Its embedded starter projects are package data, not root solution build members. See Templates for pack/install/generate/build commands and the source import register for provenance and contribution attribution.
Records live in docs/adr/. Name a new one YYYY-MM-DD-slug.md and give it a # heading with the title
alone — no numeric prefix. The older NNNN- records stay as they are; do not renumber them, and do not
continue the sequence. Sequential numbering had no reservation step, so two branches in flight always
picked the same number and one of them had to be renumbered on merge.
docs/adr/toc.md is generated. After adding or retitling a record, run:
scripts/adr/generate-toc.shand commit the result. CI runs scripts/adr/generate-toc.sh --check and fails a pull request whose index
is out of date, so the index is never hand-edited.
We aim for PRs that are easy to review, easy to reason about, and safe to merge.
Keep PRs focused on a single logical change:
- ✅ Bug fix
- ✅ Refactor (no behavior change)
- ✅ Formatting
- ✅ Dependency update
- ✅ Documentation change
- ❌ Mixing unrelated cleanups with functional changes
Why: Mixed concerns increase cognitive load, slow reviews, and increase merge risk.
If you notice cleanup opportunities while fixing a bug:
- Prefer a follow-up PR titled
refactor: ...orchore: ... - Or keep cleanup strictly limited to what is required for the fix
PRs that mix unrelated concerns may be asked to split before review continues.
A good PR includes:
- A clear problem statement
- Expected behavior
- Steps to reproduce (if applicable)
- Steps to verify the change
- Screenshots or video for UI changes (if applicable)
The easier your PR is to review, the faster it can be merged.
Smaller PRs are:
- Easier to review
- Less risky to merge
- More likely to receive timely feedback
If a change is large, consider splitting it into incremental PRs.
We use GitHub Issues to track bugs and feature requests.
When reporting a bug, please include:
- A clear summary
- Steps to reproduce
- Expected behavior
- Actual behavior
- Relevant logs or screenshots
- Sample code (if applicable)
Thorough bug reports significantly increase the chance of a fast and accurate resolution.
Elsa Workflows is an open source project, and as such, not all feature requests can be implemented immediately or on demand.
Feature development is prioritized based on a combination of the following factors:
Some features align closely with the long-term direction of Elsa and are prioritized accordingly.
Features that are backed by concrete use cases, especially in production environments, are more likely to be prioritized.
If a feature is important for your scenario, providing context about how you plan to use it is extremely helpful.
Contributions from the community are strongly encouraged.
If you are able to propose a design or submit a pull request, it can significantly accelerate progress. Maintainers are happy to collaborate and review contributions.
Elsa is actively maintained, but development capacity is limited. As a result, some features may take time to be implemented.
Organizations that require specific features or timelines can engage through commercial support.
This allows dedicated time to be allocated to specific work items and can accelerate development significantly.
- There are no guaranteed timelines for feature requests
- Some features may remain open until one of the above factors changes
- The best way to move a feature forward is to:
- Contribute a proposal or implementation
- Provide a strong real-world use case
- Sponsor or fund the work
We appreciate all feature requests and feedback — they help shape the direction of Elsa Workflows.
By contributing, you agree that your contributions will be licensed under the project's MIT License.