npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sourceregistry/cel-lite

v1.1.2

Published

Common Expression Language Lite.

Downloads

86

Readme

@sourceregistry/cel-lite

A small, dependency-free CEL-inspired expression compiler and evaluator

npm version npm downloads license Node issues

Evaluate safe, auditable expressions for identity mapping, policy checks, group assignment, and multi-tenant configuration. CEL-lite is inspired by Google's Common Expression Language, but intentionally implements a smaller deterministic subset.

Docs | npm | Issues


Installation

npm install @sourceregistry/cel-lite

CEL-lite has zero runtime dependencies and works in Node and browser runtimes.


Overview

import { compileCel } from '@sourceregistry/cel-lite';

const program = compileCel("has(user.email) ? lower(trim(user.email)) : null");

const result = program.eval({
    user: { email: '[email protected]' },
});

console.log(result); // [email protected]

Compile expressions once, then evaluate them against request-specific context objects.

const isStudent = compileCel("'student' in saml.attributes.eduPersonAffiliation");

isStudent.eval({
    saml: {
        attributes: {
            eduPersonAffiliation: ['member', 'student'],
        },
    },
}); // true

Core API

compileCel(source, options?)

Parses and validates an expression, then returns a reusable CelProgram.

import { compileCel } from '@sourceregistry/cel-lite';

const program = compileCel("coalesce(first(mail), 'n/a')", {
    maxExpressionLength: 4096,
    maxAstNodes: 2000,
});

Invalid expressions throw CelError with a message and source position when available.

program.eval(context)

Evaluates the compiled expression against a plain context object.

const email = program.eval({
    mail: ['[email protected]'],
});

Evaluation has no side effects, does not mutate the context, and only supports allow-listed functions.

program.explain(context)

Evaluates the expression and returns a trace of intermediate AST values.

const explained = compileCel("size(groups) > 0 ? groups[0] : null").explain({
    groups: ['Students', 'Staff'],
});

console.log(explained.result); // Students
console.table(explained.trace);

Use explain mode for admin previews, mapper debugging, and audit tooling. Keep trace limits configured for untrusted or high-volume inputs.


Expression Syntax

Literals

true, false, null
123, -1, 3.14
"string", 'string'
[1, 2, "a"]

Operators

==  !=  <  <=  >  >=
&&  ||  !
+   in
?:  ternary

Access

user.email
saml.attributes["urn:mace:dir:attribute-def:mail"][0]

Missing paths resolve to undefined. Object access only reads own properties. Inherited properties and the keys __proto__, constructor, and prototype are blocked everywhere, including root identifiers.

For objects, in checks own properties only:

"email" in user       // true when user has its own "email" property
"toString" in user    // false

Built-In Functions

| Function | Description | | -------------------------- | ------------------------------------------------ | | has(x) / exists(x) | Checks defined values; arrays must be non-empty | | size(x) | Length of an array/string or own-key object count | | first(x) | First array element, otherwise the value itself | | last(x) | Last array element, otherwise the value itself | | collect(a, b, ...) | Collects arguments into an array | | lower(s) / upper(s) | String casing | | trim(s) | Trim whitespace | | contains(a, b) | Array membership or string containment | | containsAny(arr, values) | True when any value matches | | startsWith(s, prefix) | String prefix check | | endsWith(s, suffix) | String suffix check | | matches(s, regex) | Guarded JavaScript regex test | | regexReplace(s, r, repl) | Guarded global JavaScript regex replace | | coalesce(a, b, ...) | First non-null, defined, non-empty-array value | | join(arr, sep) | Join array items into a string | | split(s, sep) | Split a string into an array |

Only these functions are callable. Arbitrary JavaScript functions, globals, imports, IO, network access, time access, mutation, loops, and user-defined functions are intentionally not supported.


Regex Safety

matches and regexReplace use JavaScript RegExp, but CEL-lite applies conservative checks before compilation:

  • regex pattern length is limited;
  • regex input length is limited;
  • backreferences are rejected;
  • common nested and ambiguous repetition forms are rejected;
  • invalid regex syntax is wrapped in CelError.

These guards reduce ReDoS risk without adding dependencies. JavaScript does not provide a synchronous regex timeout, so applications that accept arbitrary regex from untrusted users should run evaluation behind a host-level worker or process timeout.


Limits

CEL-lite enforces compile-time and runtime limits.

const program = compileCel("matches(email, pattern)", {
    maxExpressionLength: 4096,
    maxAstNodes: 2000,
    maxCallDepth: 50,
    maxTraceEntries: 5000,
    maxCollectionLength: 10000,
    maxStringLength: 65536,
    maxCompareDepth: 50,
    maxRegexPatternLength: 256,
    maxRegexInputLength: 4096,
});

| Option | Default | Purpose | | ----------------------- | ------- | -------------------------------------------- | | maxExpressionLength | 4096 | Maximum source string length | | maxAstNodes | 2000 | Maximum parsed AST size | | maxCallDepth | 50 | Maximum nested function calls | | maxTraceEntries | 5000 | Maximum explain-mode trace entries | | maxCollectionLength | 10000 | Maximum array/object size for expensive scans | | maxStringLength | 65536 | Maximum string length for selected helpers | | maxCompareDepth | 50 | Maximum recursive object/array compare depth | | maxRegexPatternLength | 256 | Maximum regex pattern length | | maxRegexInputLength | 4096 | Maximum input length for regex operations |


Production Guidance

  • Compile expressions before hot paths when possible and reuse CelProgram instances.
  • Treat context objects as data, not capability containers.
  • Use plain data objects or null-prototype objects for untrusted context data.
  • Keep regex support behind conservative limits, or isolate evaluation in a worker/process for hard timeouts.
  • Keep maxCollectionLength and maxCompareDepth low for tenant-controlled input.
  • Use explain() for admin tooling, not every production request.
  • Add regression tests for tenant expressions, mapping rules, and authorization conditions.
  • Keep dependency audit clean in CI, including workspace packages.

Type Reference

compileCel(source, options?)

CelProgram
CelProgram.eval(context)
CelProgram.explain(context)

CelContext
CelOptions
CelExplainEntry
CelExplainResult
CelError

Related Packages


Testing

npm test
npm run lint

License

Apache-2.0 (c) A.P.A. Slaa