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...