Cel.Compiled 0.0.6

dotnet add package Cel.Compiled --version 0.0.6
                    
NuGet\Install-Package Cel.Compiled -Version 0.0.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cel.Compiled" Version="0.0.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cel.Compiled" Version="0.0.6" />
                    
Directory.Packages.props
<PackageReference Include="Cel.Compiled" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cel.Compiled --version 0.0.6
                    
#r "nuget: Cel.Compiled, 0.0.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cel.Compiled@0.0.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cel.Compiled&version=0.0.6
                    
Install as a Cake Addin
#tool nuget:?package=Cel.Compiled&version=0.0.6
                    
Install as a Cake Tool

Cel.Compiled

NuGet Version

Cel.Compiled is a high-performance .NET implementation of the Common Expression Language (CEL). It compiles CEL source text into optimized, reusable CelProgram<TContext, TResult> objects, making it ideal for high-frequency evaluation in rule engines, policy enforcement, and dynamic filtering.

It is designed for scenarios where expressions are compiled once and evaluated many times.

Key Features

  • High Performance: Compiles to reusable programs with an unrestricted delegate helper for near-native execution speed.
  • Modern .NET: Built for .NET 10+ with optimized memory usage.
  • Broad Input Support: Bind to POCOs, JsonElement, JsonNode, or custom type descriptors.
  • Spec-Compliant: Comprehensive support for CEL operators, functions, macros, and optional types.
  • Extensible: Easily register custom functions and receiver-style extensions.

Installation

Install via NuGet:

dotnet add package Cel.Compiled

When To Use It

Cel.Compiled is a strong fit when you:

  • evaluate the same expression repeatedly against many inputs
  • need CEL support over POCOs, JsonElement, JsonNode, or descriptor-backed CLR types
  • want custom functions or curated extension bundles without leaving .NET

If your workload is mostly one-off parse-and-run calls, an interpretive library may have lower setup cost. Cel.Compiled is optimized for warm execution.

Basic Usage

using Cel.Compiled;

// 1. Define a context (POCO or JSON)
var context = new { User = new { Age = 25, Status = "active" } };

// 2. Compile once
var program = CelExpression.Compile<dynamic, bool>("User.Age >= 18 && User.Status == 'active'");

// 3. Evaluate many times
bool isAllowed = program.Invoke(context);

Using JSON Inputs

using System.Text.Json;

var json = JsonDocument.Parse("""{"age": 25, "status": "active"}""").RootElement;
var program = CelExpression.Compile<JsonElement, bool>("age >= 18 && status == 'active'");
bool result = program.Invoke(json);

Compile Options

Custom functions, extension bundles, and type descriptors are configured through CelCompileOptions.

using Cel.Compiled;
using Cel.Compiled.Compiler;

var registry = new CelFunctionRegistryBuilder()
    .AddStandardExtensions()
    .Build();

var options = new CelCompileOptions
{
    FunctionRegistry = registry
};

var program = CelExpression.Compile<JsonElement, bool>(
    "name.trim().lowerAscii() == 'alice'",
    options);

Runtime Safety For Untrusted Inputs

Use Invoke(context, runtimeOptions) when evaluating untrusted or multi-tenant expressions.

var program = CelExpression.Compile<JsonElement, bool>("items.all(x, x > 0)");

var allowed = program.Invoke(
    json,
    new CelRuntimeOptions
    {
        MaxWork = 10_000,
        MaxComprehensionDepth = 4,
        Timeout = TimeSpan.FromMilliseconds(100),
        RegexTimeout = TimeSpan.FromMilliseconds(25)
    });

MaxWork is intentionally narrow. It counts compiler-owned repeated-work checkpoints such as comprehensions and regex-backed operations, not every AST node or every CPU instruction.

Performance

Cel.Compiled is designed for runtime speed. By compiling to delegates and minimizing allocations during evaluation, it substantially outperforms the other .NET CEL libraries in steady-state runtime benchmarks.

Fresh benchmark run on 2026-03-20 from Cel.Compiled.Benchmarks/Program.cs, using the CelNetComparisonBenchmarks suite on:

  • .NET SDK 10.0.104
  • .NET runtime 10.0.4
  • AMD Ryzen 9 7900X

Comparison workload:

  • 1 + 2 * 3 == 7
  • 'hello world'.contains('world')
  • [1, 2, 3].exists(x, x == 2)

Steady-state warm execution after compilation:

Library Mean Relative to Cel.Compiled Allocated
Native C# 7.30 ns 1.3x faster 0 B
Cel.Compiled 9.39 ns 1.0x 0 B
Cel.NET 405.71 ns 43.2x slower 1360 B
Telus CEL 3.03 us 322.7x slower 8808 B

Build-and-run from scratch for the same three expressions:

Library Mean Relative to Cel.Compiled Allocated
Cel.Compiled 678.73 us 1.0x 50,089 B
Cel.NET 1.10 ms 1.6x slower 3,398,264 B
Telus CEL 35.57 us 19.1x faster 124,528 B

The important tradeoff is straightforward: Cel.Compiled stays close to native C# on the hot path, but it still pays an upfront compile cost for that speed. On this benchmark it remains far ahead of Cel.NET during warm execution, while Telus CEL has the fastest build-and-run path among the compared CEL libraries.

To reproduce the comparison:

dotnet run -c Release --project Cel.Compiled.Benchmarks -- --filter "*CelNetComparisonBenchmarks*"

BenchmarkDotNet writes detailed reports to BenchmarkDotNet.Artifacts/results/.

Supported Features

  • Arithmetic: +, -, *, /, %
  • Equality & Ordering: ==, !=, <, <=, >, >=
  • Logical: &&, ||, !
  • Conditionals: cond ? a : b
  • Collections: list, map, in operator, indexing
  • Macros: all, exists, exists_one, map, filter
  • Optional safe-navigation: obj.?field, list[?index], map[?key]
  • Standard Extensions: String, Math, List, Set, Base64, and Regex extension bundles

Major Differences And Current Gaps

Cel.Compiled aims to be a practical, high-performance .NET CEL runtime, not a line-for-line clone of cel-go. The biggest current differences are:

  • No dedicated static checking phase: cel-go has an explicit parse → check → eval pipeline with a checked AST and richer type metadata. Cel.Compiled does perform compile-time binding and overload validation, but it does not currently expose a separate Env.Check()-style phase.
  • Lighter environment model: variables are primarily inferred from TContext, with functions and types supplied through CelCompileOptions. There is not yet a single first-class environment object that declaratively models variables, constants, functions, types, and checker inputs together.
  • Runtime-first design: the library is strongest when you compile once and reuse delegates. It is less optimized for one-off evaluation or tooling workflows built around checked AST inspection.
  • No portable compiled-expression serialization: compiled delegates are cached in-process, but there is no cel-go-style serialized checked-expression or compiled-plan format that can be saved and reloaded across processes.
  • Partial evaluation and residualization are not implemented: unknown propagation, residual AST generation, and richer evaluation-state tooling are still gaps.
  • Some cel-go extension/library areas remain incomplete: the shipped string, list, set, base64, and regex bundles cover the common surface, but math bitwise helpers and a few advanced areas still remain.
  • Optional support is intentionally scoped: the core optional navigation and helper subset is implemented, but optional aggregate literal entries and broader helper parity are still narrower than cel-go.
  • Regex behavior is platform-based rather than exact RE2 parity: the runtime uses the .NET regex engine and documents CEL-facing behavior, but it does not aim for byte-for-byte RE2 compatibility.
  • Runtime safety controls exist but are intentionally narrow: CelRuntimeOptions provides cancellation, timeout, regex timeout, work limits, and comprehension-depth limits, but MaxWork is a practical checkpoint-based budget rather than full instruction-level metering.

Some of these may be addressed in the future but the focus is on providing a fast, reliable CEL runtime for .NET.

More Details

License

Cel.Compiled is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.6 30 3/20/2026
0.0.5 34 3/19/2026
0.0.4 30 3/17/2026
0.0.3 33 3/17/2026
0.0.2 47 3/16/2026