# @bpmn-io/feel-analyzer

> Static FEEL expression analyzer

Latest version **0.5.1** (published 2026-09-08) · MIT license · 0 weekly downloads

## Install

```sh
npm install @bpmn-io/feel-analyzer
pnpm add @bpmn-io/feel-analyzer
yarn add @bpmn-io/feel-analyzer
bun add @bpmn-io/feel-analyzer
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.5.1 |
| Published | 2026-09-08 |
| First published | 2026-02-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >= 20 |
| Dependencies | 2 |
| Unpacked size | 65.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | Simon Steinrücken |
| Maintainers | bpmn-io-admin, nikku, barmac, philippfromme, maxtru, skaiir-camunda, vsgoulart, barinali, ev-camunda, jarekdanielak, alekseymanetov |
| Keywords | feel, bpmn-io, analyzer |

## Links

- npm: https://www.npmjs.com/package/@bpmn-io/feel-analyzer
- Repository: https://github.com/bpmn-io/feel-analyzer
- Homepage: https://github.com/bpmn-io/feel-analyzer#readme
- Issues: https://github.com/bpmn-io/feel-analyzer/issues
- npm.io page: https://npm.io/package/@bpmn-io/feel-analyzer

## Dependencies (2)

- [@lezer/common](https://npm.io/package/@lezer/common.md) ^1.5.2
- [@bpmn-io/lezer-feel](https://npm.io/package/@bpmn-io/lezer-feel.md) ^3.0.1

## Recent versions

- 0.5.1 (latest) — 2026-09-08
- 0.5.0 — 2026-07-08
- 0.4.0 — 2026-07-01
- 0.3.0 — 2026-05-19
- 0.2.2 — 2026-05-12
- 0.2.1 — 2026-05-08
- 0.2.0 — 2026-05-08
- 0.1.0 — 2026-02-18

## README

# FEEL Analyzer

> A library for analyzing FEEL (Friendly Enough Expression Language) expressions.

[![CI](https://github.com/bpmn-io/feel-analyzer/workflows/CI/badge.svg)](https://github.com/bpmn-io/feel-analyzer/actions?query=workflow%3ACI)

## Installation

```bash
npm install @bpmn-io/feel-analyzer
```

## Usage

To get started, create a `FeelAnalyzer` instance:

```javascript
import { FeelAnalyzer } from '@bpmn-io/feel-analyzer';

const analyzer = new FeelAnalyzer();
```

Analyze a FEEL expression to extract input variables:

```javascript
const result = analyzer.analyzeExpression('x + y');

console.log(result.valid); // true
console.log(result.inputs);
// [
//   { name: 'x' },
//   { name: 'y' }
// ]
```

Configure the FEEL dialect (expression or unary tests):

```javascript
const analyzer = new FeelAnalyzer({
  dialect: 'unaryTests' // defaults to 'expression'
});
```

### Builtins

You can provide `builtins` and `reservedNameBuiltins` to exclude built-in names from input detection. Use [`@camunda/feel-builtins`](https://github.com/camunda/feel-builtins) to supply these:

```javascript
import { FeelAnalyzer } from '@bpmn-io/feel-analyzer';
import { builtins, reservedNameBuiltins } from '@camunda/feel-builtins';

const analyzer = new FeelAnalyzer({
  dialect: 'expression',
  parserDialect: 'camunda',
  builtins,
  reservedNameBuiltins
});

const result = analyzer.analyzeExpression('sum(orders.amount) > 100');

console.log(result.inputs);
// [
//   {
//     name: 'orders',
//     type: 'List',
//     entries: [
//       { name: 'amount' }
//     ]
//   }
// ]
```

### Input Variables

The analyzer extracts input variables with type information, including nested structures. The data model is aligned with [variable-resolver](https://github.com/bpmn-io/variable-resolver):

```javascript
const result = analyzer.analyzeExpression('person.name = "John" and scores[1] > 10');

console.log(result.inputs);
// [
//   {
//     name: 'person',
//     type: 'Context',
//     entries: [
//       { name: 'name' }
//     ]
//   },
//   {
//     name: 'scores',
//     type: 'List'
//   }
// ]
```

### Invoked Functions

The analyzer extracts all function invocations from the expression, sorted by name and deduplicated. Each function is classified as `builtin` or `user` based on the provided `builtins` list:

```javascript
import { FeelAnalyzer } from '@bpmn-io/feel-analyzer';
import { camundaBuiltins, camundaReservedNameBuiltins } from '@camunda/feel-builtins';

const analyzer = new FeelAnalyzer({
  parserDialect: 'camunda',
  builtins: camundaBuiltins,
  reservedNameBuiltins: camundaReservedNameBuiltins
});

const result = analyzer.analyzeExpression('from json(sum(myHelper(x)))');

console.log(result.functions);
// [
//   { name: 'from json', type: 'builtin' },
//   { name: 'myHelper', type: 'user' },
//   { name: 'sum', type: 'builtin' }
// ]
```

### Analyzing an Already-Parsed Tree

If you already have a parsed syntax tree—for example from a CodeMirror editor using the same parser—you can analyze it directly with `analyzeTree`, avoiding a redundant parse:

```javascript
const analyzer = new FeelAnalyzer();

const expression = 'x + y';
const tree = analyzer.parser.parse(expression);

const result = analyzer.analyzeTree(tree, expression);
```

The tree must come from a parser configured consistently with the analyzer (same `dialect`, `parserDialect`, and `reservedNameBuiltins`) - such as the provided `analyzer.parser`. A tree parsed with a different configuration may yield incorrect results.

## Related

- [@bpmn-io/lezer-feel](https://github.com/bpmn-io/lezer-feel) - FEEL language definition for the [Lezer](https://lezer.codemirror.net/) parser system

## License

MIT

---
_Source: https://npm.io/package/@bpmn-io/feel-analyzer · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
