Native C# CEL Implementation

jackedEngineer1 pts0 comments

NuGet Gallery<br>| Celly 1.1.0

Celly

1.1.0

.NET 8.0

This package targets .NET 8.0. The package is compatible with this framework or higher.

.NET CLI

PMC

PackageReference

CPM

Paket CLI

Script & Interactive

File-Based Apps

Cake

dotnet add package Celly --version 1.1.0

Copy

NuGet\Install-Package Celly -Version 1.1.0

Copy

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.

Copy

For projects that support PackageReference, copy this XML node into the project file to reference the package.

Directory.Packages.props

Copy

Project file

Copy

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 1.1.0

Copy

The NuGet Team does not provide support for this client. Please contact its maintainers for support.

#r "nuget: Celly, 1.1.0"

Copy

#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@1.1.0

Copy

#: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=1.1.0

Install as a Cake Addin

Copy

#tool nuget:?package=Celly&version=1.1.0

Install as a Cake Tool

Copy

The NuGet Team does not provide support for this client. Please contact its maintainers for support.

README

Frameworks

Dependencies

Used By

Versions

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<br>(30 testdata files, pinned @ 59505c1), verified in CI on Linux, Windows, and macOS.

Status: 1.0 — stable public API (snapshot-tested), 100% conformance, fuzz-hardened.

⚡ Performance: in the same class as the reference Go implementation — within ~1.2× of cel-go on simple expressions, and faster than cel-go on comprehension-heavy ones (15 µs vs 23 µs). Faster than Cel.NET across the board. See Performance.

📖 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;<br>using Celly.Checking;<br>using Celly.Types;

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

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

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

Packages

Package<br>Contents<br>Dependencies

Celly<br>Lexer, parser, macros, type checker, evaluator, standard library, all extension libraries<br>None

Celly.Protobuf<br>Protobuf types: message construction & field access, well-known types (Timestamp/Duration/Struct/Any/wrappers), enums (legacy int and strong modes), proto2 extensions<br>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...

celly package copy nuget version protobuf

Related Articles