Library / SDK
microsoft/RulesEngine avatar
microsoft/RulesEngine

microsoft/RulesEngine: a .NET rules engine that keeps business logic out of your code

A fast and reliable .NET Rules Engine with extensive Dynamic expression support

4,353 stars617 forksC#MIT

At a glance

What is it?
RulesEngine is an MIT-licensed NuGet library that stores business rules as JSON workflows and evaluates them against your objects. It suits .NET teams who need to change discount or eligibility logic without redeploying, and it stops being the right tool once rules need state, sequencing or human review.
Who is it for?
Adopt RulesEngine when your rules are stateless condition sets over an input object and the people changing them can work with JSON that follows the workflow schema. Do not adopt it when rules must trigger side effects, wait for an approval, or maintain state across steps; the README describes a wrapper that feeds inputs in and handles outputs, not a workflow orchestrator.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 19 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem RulesEngine solves, and who has it

The README frames the goal plainly: abstracting business logic, rules and policies out of a system so that a change in rules does not affect the core system. That is a deployment problem more than a programming problem. If a discount threshold lives in a C# if-statement, changing it means a code review, a build and a release. RulesEngine moves that threshold into a JSON document that adheres to the workflow schema, so the core assembly stays untouched.

The intended user is a .NET team that already has an object to evaluate. The README's own example takes an input1 with country, loyaltyFactor and totalPurchasesToDate, and decides between a 10 percent and a 20 percent discount. Nothing in that example requires a database, a message broker or a service. You have a class, you have conditions, and you want the conditions somewhere else.

It is a poor fit for anyone who wants rules to do things. The README describes the library as taking rules and input messages, then handing output back to a wrapper you write. Side effects, retries, waiting and approval steps are the wrapper's job, not the engine's.

How the workflow schema and lambda evaluation fit together

The unit of configuration is a workflow. A workflow has a WorkflowName and a list of Rules. Each rule carries a RuleName, a SuccessEvent, an ErrorMessage, a RuleExpressionType and an Expression. In the README's discount example, RuleExpressionType is LambdaExpression and the Expression is a string such as input1.country == "india" AND input1.loyaltyFactor <= 2 AND input1.totalPurchasesToDate >= 5000. The engine parses that string and evaluates it against the object you pass in.

The result is not a boolean. ExecuteAllRulesAsync returns a List<RuleResultTree>, which the README says gives information about whether each rule passed or failed. That shape matters: you get one entry per rule, so a caller can report which conditions failed rather than only that the whole set did. SuccessEvent and ErrorMessage travel with each rule, which is how the README's example communicates the discount percentage as a string.

Rules live in any store you like. The README lists Azure Blob Storage, Cosmos DB, Azure App Configuration, Entity Framework, SQL Servers and file systems. The library does not fetch them. You deserialize into the workflow model and construct the engine, which is why the README describes a wrapper as the normal integration shape.

The schema file at schema/workflow-schema.json is the authority on what the JSON may contain. The README points at it directly, and it is the right first read before writing rules by hand.

Installing RulesEngine and running a first workflow

Installation is a NuGet reference. The README says to download the latest version of the NuGet package from nuget.org and refer it into your project, which in practice means adding the package to your csproj:

bash
dotnet add package RulesEngine

After that, the README's code-only path builds the rules in C# rather than JSON. This is the fastest way to confirm the engine works in your project before you move rules into a store:

c#
List<Rule> rules = new List<Rule>();

Rule rule = new Rule();
rule.RuleName = "Test Rule";
rule.SuccessEvent = "Count is within tolerance.";
rule.ErrorMessage = "Over expected.";
rule.Expression = "count < 3";
rule.RuleExpressionType = RuleExpressionType.LambdaExpression;
rules.Add(rule);

var workflows = new List<Workflow>();
Workflow exampleWorkflow = new Workflow();
exampleWorkflow.WorkflowName = "Example Workflow";
exampleWorkflow.Rules = rules;
workflows.Add(exampleWorkflow);

var bre = new RulesEngine.RulesEngine(workflows.ToArray());

With the engine constructed, execution is one call. The README shows the JSON-driven form, where workflowName is the workflow you want and input is the object to check:

c#
List<RuleResultTree> response = await rulesEngine.ExecuteAllRulesAsync(workflowName, input);

What you should see is one RuleResultTree per rule in the workflow, each indicating pass or fail. If you are loading rules from a database through Entity Framework, the README's demo uses a ThenInclude chain to pull nested rules, with the note that each level of nested rules needs its own ThenInclude. A demo app is available in the demo directory of the repository if you would rather read working code than assemble it.

Where RulesEngine stops being the right tool

The engine evaluates expressions. It does not sequence anything. If your process is "check eligibility, then reserve inventory, then wait for a manager, then notify the customer", RulesEngine covers the first step and nothing after it. The README is explicit that a wrapper handles the output using appropriate means, which is a polite way of saying the orchestration is yours to build.

Expression strings are also a sharp edge. The README's examples reference input1.country and input1.loyaltyFactor by name. Those names have to resolve against the object you pass, and the README does not describe what happens when they do not. Nothing in the README documents a compile step that would catch a typo in a rule before runtime, so a rule store edited by hand can hold an expression that fails only when that workflow executes.

The README does not document rollback, versioning of stored rules, or a dry-run mode. If you need to know which rules were active when a decision was made, you are storing that yourself. Combined with the fact that rules live in whatever store you choose, the audit story is entirely your responsibility.

Finally, this is a .NET library. The related search data shows people looking for a TypeScript rules engine, and the README offers nothing for that. There is no JavaScript package here, no REST service, and no language binding. If your rule evaluation has to happen outside the .NET runtime, this project does not reach it.

RulesEngine compared with a general workflow engine

The nearest alternative in kind is a workflow engine such as Drools on the JVM, which the search data shows people comparing directly. The difference is not speed, it is what the two things model. RulesEngine takes a flat set of rules in a workflow and evaluates all of them against one input, returning a result tree. A workflow engine models transitions, state and long-running processes, and it typically owns the persistence of where a process currently sits.

That distinction decides the choice. If your logic is "given this order, which discounts apply", RulesEngine is the smaller tool and the JSON schema is easy to read. If your logic is "this order moves through five states over three days", a workflow engine carries the state for you and RulesEngine leaves it to your wrapper.

There is a third option worth naming: keeping the conditions in C# and shipping them as code. That is cheaper until the first time a business user needs a threshold changed on a Friday. The whole point of the library is that this trade stops being attractive.

For editing rules, the README points to a separate project, RulesEngine Editor, with its own NuGet package written in Blazor and a hosted demo. It is a third-party tool, not part of this repository, and the README links it as such.

Maintenance, licensing and what upgrading costs you

The repository is not archived and the last push was on 2026-09-11. The most recent release listed is v6.0.0 from 2025-06-04, following v5.0.6 and v5.0.5 earlier in 2025. There is a CHANGELOG.md at the repository root, which is where the actual breaking-change detail lives; the README does not carry an upgrade guide.

The supported target frameworks are .NET 6, .NET 8, .NET 9, .NET 10, .NET Standard 2.0 and .NET Standard 2.1. That range is wide enough that most .NET codebases can reference the package, but it also means the library carries compatibility surface it cannot drop quickly. A major version bump such as 5.x to 6.0 is the moment to read the changelog rather than assume the workflow schema is unchanged.

Upgrade cost concentrates in two places: the workflow JSON, which is validated against schema/workflow-schema.json, and the expression strings inside it. Neither is checked by the compiler. Before moving a version, run your stored workflows through the engine in a test and confirm each rule still evaluates. That is a concrete step, not a general caution.

The licence is MIT, stated in the repository's LICENSE file. MIT permits commercial use and modification with the copyright notice retained. This is a description of the licence text, not legal advice; if your organisation has rules about bundled dependencies, check the LICENSE file and your own policy.

Editorial conclusion

Adopt RulesEngine when your rules are stateless condition sets over an input object and the people changing them can work with JSON that follows the workflow schema. Do not adopt it when rules must trigger side effects, wait for an approval, or maintain state across steps; the README describes a wrapper that feeds inputs in and handles outputs, not a workflow orchestrator. Before committing, verify that your target framework is one of the listed ones, that your rule store can hand the library a deserialized workflow array, and that your expressions only touch members your input classes actually expose.

Frequently asked questions

What is Microsoft RulesEngine?

It is a .NET library and NuGet package from Microsoft that abstracts business rules out of a system, storing them as workflows that follow a JSON schema and evaluating them against an input object. It is distributed as the RulesEngine package and licensed under MIT.

What does a rules engine do?

In this project, it takes a workflow of rules and an input object, evaluates each rule's lambda expression, and returns a RuleResultTree per rule indicating whether it passed or failed. The rules themselves live outside the core system in whatever store you choose.

Can you give me an example of a rule engine?

The README's discount example defines a rule with RuleExpressionType LambdaExpression and the expression input1.country == "india" AND input1.loyaltyFactor <= 2 AND input1.totalPurchasesToDate >= 5000, with SuccessEvent "10" returned when it passes.

Official sources

  1. License: MIT
  2. microsoft/RulesEngine on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/microsoft-rulesengine.svg)](https://hysenlabs.com/projects/microsoft-rulesengine)