It is clear that Vyshyvanka is more than just code — it is an ecosystem. The true power of an open-source workflow engine lies in its community. Today, we want to talk about how you can get involved, whether you are interested in pushing the boundaries of the core engine or building specialized solutions with custom plugins.
The Core Engine vs. The Plugin Ecosystem
A common question we get is: 'Should I contribute a PR to the core engine, or should I build a separate plugin?' The answer depends entirely on the scope of your contribution.
When to Contribute to Core
The core engine (Vyshyvanka.Core, Vyshyvanka.Engine, Vyshyvanka.Api, Vyshyvanka.Designer) should be reserved for changes that benefit every user of the platform. Good candidates for core contributions:
- Performance improvements to the execution pipeline
- New fundamental port types or expression functions
- Bug fixes in the engine, validation, or persistence layers
- Enhancements to the Designer UI (canvas, node editor, property editors)
- Improvements to the API surface (new endpoints, better error responses)
- Documentation improvements
These changes require careful review and testing because they impact every installation. We encourage PRs here, but we also ask that you open an issue first so we can discuss the architectural impact.
When to Build a Plugin
Plugins (./plugins/) are the best way to extend functionality without increasing the maintenance burden of the core. Good candidates for plugins:
- Integration with a specific third-party SaaS tool (CRM, CI/CD, monitoring)
- Custom nodes specific to your industry or use case
- Experimental node behaviors that are not yet ready for core
- Proprietary integrations you want to keep separate from the open source project
Plugins are independent, versionable, and can be maintained outside the core release cycle. They empower you to solve your specific problems immediately without waiting for a core release.
Project Structure at a Glance
Understanding where things live is key to contributing effectively:
Vyshyvanka/
├── src/
│ ├── Vyshyvanka.Core/ # Domain layer (zero dependencies)
│ ├── Vyshyvanka.Engine/ # Execution engine, persistence, plugins
│ ├── Vyshyvanka.Api/ # REST API
│ ├── Vyshyvanka.Designer/ # Blazor WASM UI
│ ├── Vyshyvanka.AppHost/ # .NET Aspire orchestration
│ └── Vyshyvanka.ServiceDefaults/
├── plugins/
│ ├── Vyshyvanka.Plugin.AdvancedHttp/
│ ├── Vyshyvanka.Plugin.GitLab/
│ ├── Vyshyvanka.Plugin.Jira/
│ └── Vyshyvanka.Plugin.Tmplt/ # Starter template!
├── tests/
│ └── Vyshyvanka.Tests/
└── docs/
Dependencies flow strictly downward. Core has zero dependencies. Engine depends on Core. Api depends on Core and Engine. Plugins depend only on Core.
Getting Started with Plugin Development
The fastest way to start is with the template plugin:
-
Copy the template: Duplicate
plugins/Vyshyvanka.Plugin.Tmplt/and rename it. -
Update
PluginInfo.cs: Set your plugin ID, name, version, and author. -
Create your nodes: Inherit from
BasePluginNode, add[NodeDefinition]and[ConfigurationProperty]attributes. - Build and test: The test project can reference your plugin directly.
- Package: Publish as a NuGet package for easy distribution.
Here is the minimal structure:
// PluginInfo.cs
[assembly: Plugin(
"com.yourorg.myplugin",
Name = "My Plugin",
Version = "1.0.0",
Description = "Does something useful",
Author = "Your Name")]
// Nodes/MyCustomNode.cs
[NodeDefinition(
Name = "My Custom Action",
Description = "Does the thing",
Icon = "fa-solid fa-star")]
[ConfigurationProperty("apiUrl", "string", Description = "API endpoint", IsRequired = true)]
public class MyCustomNode : BasePluginNode
{
public override string Type => "my-custom-action";
public override NodeCategory Category => NodeCategory.Action;
public override async Task<NodeOutput> ExecuteAsync(NodeInput input, IExecutionContext context)
{
var apiUrl = GetRequiredConfigValue<string>(input, "apiUrl");
// Your logic here...
return SuccessOutput(JsonSerializer.SerializeToElement(new { result = "done" }));
}
}
Contributing to Core: Guidelines
If you want to contribute to the core:
- Open an issue first: Describe the problem and your proposed solution. This helps us maintain consistency and prevents wasted effort.
-
Follow conventions: File-scoped namespaces, primary constructors for DI,
CancellationTokenin every async method, AwesomeAssertions in tests. - Write tests: Every change needs appropriate test coverage — unit tests for logic, integration tests for API changes.
- Respect the dependency rules: Never introduce an upward or circular reference between projects.
- Check the ripple effect: If you change an interface in Core, update all implementations in Engine.
Running the Full Stack
# Build everything
dotnet build
# Run all tests
dotnet test
# Start the full application (API + Designer)
dotnet run --project src/Vyshyvanka.AppHost
# Start just the API
dotnet run --project src/Vyshyvanka.Api
A Growing Ecosystem
Every plugin you build and every bug you fix makes Vyshyvanka more valuable for everyone else. Whether you are an enterprise developer building mission-critical workflows or a hobbyist automating your home server, your contribution helps shape the future of open-source workflow automation.
We are excited to see what you build.
In the final part of this series, we will discuss Part 15: Workflow Patterns and Recipes - Data Transformation. Stay tuned!
Check out the project source code here: https://github.com/homolibere/Vyshyvanka






















