Celly 0.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Celly --version 0.2.0
                    
NuGet\Install-Package Celly -Version 0.2.0
                    
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="Celly" Version="0.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Celly" Version="0.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Celly" />
                    
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 Celly --version 0.2.0
                    
#r "nuget: Celly, 0.2.0"
                    
#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 Celly@0.2.0
                    
#: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=Celly&version=0.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Celly&version=0.2.0
                    
Install as a Cake Tool

Celly

A native C#/.NET implementation of Google's Common Expression Language (CEL).

Celly is written from scratch in pure managed C# — no WASM shims, no Go-compiled artifacts, no native library bindings.

Conformance: 2,456 / 2,456 (100%) of the official cel-spec conformance suite (30 testdata files, pinned @ 59505c1), verified in CI on Linux, Windows, and macOS.

📖 Documentation: bsid.io/celly — user guide plus a deep-dive internals track explaining how the lexer, parser, macros, type checker, evaluator, and protobuf integration work.

Why Celly?

CEL is the expression language behind Kubernetes admission policies (ValidatingAdmissionPolicy), Envoy RBAC, Google Cloud IAM conditions, gRPC protovalidate, and more. Official implementations exist for Go, C++, Java, and Rust — but not .NET. Celly fills that gap with a conformance-verified native implementation.

using Celly;
using Celly.Checking;
using Celly.Types;

var env = CelEnv.Create(new CelEnvSettings
{
    Declarations =
    [
        new VariableDecl("request", CelType.Map(CelType.String, CelType.Dyn)),
    ],
});

var program = env.Compile("request.user.startsWith('admin-') && size(request.groups) > 0");

var result = program.Eval(new Dictionary<string, object?>
{
    ["request"] = new Dictionary<string, object?>
    {
        ["user"] = "admin-alice",
        ["groups"] = new[] { "ops" },
    },
});
// result => BoolValue.True

Packages

Package Contents Dependencies
Celly Lexer, parser, macros, type checker, evaluator, standard library, all extension libraries None
Celly.Protobuf Protobuf types: message construction & field access, well-known types (Timestamp/Duration/Struct/Any/wrappers), enums (legacy int and strong modes), proto2 extensions Celly, Google.Protobuf

Use Celly alone to evaluate expressions over .NET dictionaries/lists/primitives; add Celly.Protobuf when your data is protobuf messages.

Feature checklist

  • Full standard library: operators with CEL semantics (checked int64/uint64 arithmetic, cross-type numeric comparisons, IEEE doubles), size/in/indexing, all type conversions with Go-compatible formatting, RE2-semantics matches() (via .NET's linear-time NonBacktracking engine), nanosecond-precision timestamps/durations with IANA timezone accessors
  • Macros: has, all, exists, exists_one, map, filter (+ two-variable comprehensions)
  • Type checker: gradual typing with dyn, parameterized-type unification, container (C.name) resolution, comprehension-variable shadowing per spec
  • Optionals: optional.of/ofNonZeroValue/none, a.?b, a[?b], [?e], {?k: v}, orValue, optMap/optFlatMap, full optional chaining
  • Extension libraries (opt-in via CelEnvSettings.Libraries): strings (incl. format and strings.quote), math, encoders (base64), bindings (cel.bind), block (cel.block), two-var comprehensions, proto2 extensions (proto.getExt/hasExt), networking (net.IP/net.CIDR)
  • Protobuf: message construction with WKT collapse (wrappers → primitives, Struct/Value/ListValue → map/dyn/list), Any pack/unpack with bytewise fallback, presence-aware field-wise message equality, proto2 extension fields, strong-enum mode (ProtoTypeRegistry.FromFiles(strongEnums: true, …)) where enums are distinct named types — an opt-in the reference Go implementation doesn't offer
  • First-class ASTs: traversal/inspection tools (AstTools), lossless conversion to/from the canonical cel.expr protos (ParsedExpr/CheckedExpr incl. type & reference maps) for caching and cross-implementation interop, and a precedence-aware unparser (AST → source, macros restored to original form)
  • Thread safety: CelEnv and CelProgram are immutable; programs are safe for concurrent evaluation
// Extensions are opt-in libraries:
var env = CelEnv.Create(new CelEnvSettings
{
    Libraries = [Celly.Extensions.StringsLibrary.Instance, Celly.Extensions.MathLibrary.Instance],
});
env.Compile("'%d apples'.format([math.greatest(3, 7, 5)])").Eval(); // "7 apples"

Building

Requires the .NET 8 SDK. protoc is only needed to refresh vendored conformance data.

dotnet build Celly.sln
dotnet test                          # unit + conformance suites
tools/vendor-conformance.sh          # re-vendor cel-spec protos/testdata (pinned commit)

Conformance methodology

Celly vendors the official suite (30 SimpleTestFile textprotos, pre-encoded to binary at vendoring time since Google.Protobuf C# has no textproto parser). Each of the 2,456 conformance cases is an individual xUnit test. testdata/known-failures.txt is a ratcheting skip-list — a listed test that starts passing fails CI until the list is updated — and it is now empty.

The suite's strong_* enum sections re-run shared expressions under the alternate strong-enum semantics they document (mutually exclusive with the default legacy sections); the harness runs those sections with Celly's strong-enum mode enabled, so both semantics are fully verified.

License

Apache-2.0 (matching the CEL ecosystem).

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Celly:

Package Downloads
Celly.Protobuf

Protobuf integration for Celly (CEL for .NET): message types, well-known types, enums, and cel.expr AST interop.

Celly.Protovalidate

protovalidate for .NET: validate protobuf messages against buf.validate rules, powered by the Celly CEL engine.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 929 7/18/2026
1.1.0 141 7/17/2026
1.0.0 114 7/17/2026
0.3.0 125 7/17/2026
0.2.0 125 7/17/2026
0.1.0 120 7/17/2026