{"id":23231673,"url":"https://github.com/danielduarte/es-eval","last_synced_at":"2025-10-26T12:03:51.578Z","repository":{"id":57226925,"uuid":"463941918","full_name":"danielduarte/es-eval","owner":"danielduarte","description":"Run JavaScript safely","archived":false,"fork":false,"pushed_at":"2024-09-26T22:50:07.000Z","size":205,"stargazers_count":7,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-19T16:54:44.094Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielduarte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-26T19:03:10.000Z","updated_at":"2024-11-24T21:20:35.000Z","dependencies_parsed_at":"2025-08-19T16:34:17.706Z","dependency_job_id":"0a630543-0ca9-435b-b23a-e4f45a212c01","html_url":"https://github.com/danielduarte/es-eval","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/danielduarte/es-eval","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielduarte%2Fes-eval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielduarte%2Fes-eval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielduarte%2Fes-eval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielduarte%2Fes-eval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielduarte","download_url":"https://codeload.github.com/danielduarte/es-eval/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielduarte%2Fes-eval/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273403823,"owners_count":25099299,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-19T02:15:33.157Z","updated_at":"2025-10-26T12:03:46.543Z","avatar_url":"https://github.com/danielduarte.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# es-eval\n\nEvaluate JavaScript expressions safely.\nNo more being afraid of what the users enter!\n\n:game_die: [Playground](https://danielduarte.github.io/es-eval-playground/) (pre-release version)\n\n## Installation\n\n```bash\nnpm i es-eval\n```\n\n## Usage\n\n```js\n// Simple expression\nconst esEval = require('es-eval');\n\nconst result = esEval('1 + 2');\nconsole.log(result); // Output: 3\n```\n\n```js\n// User values\nconst esEval = require('es-eval');\n\nconst result = esEval('1 + x', { x: 4 });\nconsole.log(result); // Output: 5\n```\n\nOr more complex examples:\n\n```js\n// IIFE example\nconst esEval = require('es-eval');\n\nconst exp = `(() =\u003e {\n  const out = [];\n\n  const callback = () =\u003e {\n    out.push('callback() called');\n  };\n\n  const main = function (param, cb) {\n    out.push('main() started with param = \"' + param + '\"');\n    cb();\n    out.push('main() finished');\n  };\n\n  main('My value', callback);\n\n  return out;\n})()`;\n\nconsole.log(esEval(exp));\n// Output: [\n//   'main() called with My value',\n//   'Callback called!',\n//   'main() finished'\n// ]\n```\n\n```js\n// Hangup protection in infinite loop\nconst esEval = require('es-eval');\n\ntry {\n  esEval(`(() =\u003e {\n    while (true) {}\n  })()`);\n} catch (err) {\n  console.log(err.message); // Output: 'Evaluation timeout'\n}\n```\n\n# Features\n\n| Feature | Notes |\n|---------|-------|\n| Hangup protection | The execution of any user inputs is protected against intentional or unintentional hangups. Since it is mathematically proven that the [halting problem] is undecidable, hence it cannot be automatically computed, this protection is based on a configurable timeout. |\n| Primitive values | `number`, `string`, `boolean` and `undefined` values. |\n| Objects | `{ key: 'value' }`, `null`, built-in static methods: `Object.entries()`, `Object.keys()`, `Object.values()` |\n| Arrays | `[1, 2, 3]`, built-in properties and methods: `length`, `push`, `pop`, `shift`, `ushift`, `slice`, `splice`, `forEach`, `map`, `filter`, `reduce`, `includes` |\n| Arrow function expressions | `(x, y) =\u003e x + y` |\n| Standard function expressions | `function () { return 'value'; }` |\n| Closures | |\n| Nested expressions | `(a \u003c (b + 1) \u0026\u0026 a - (a \u003c ([1, 2].map(x =\u003e 1 + x)).length))`  |\n| Callbacks | `cb =\u003e { cb(); return 1; }` |\n| Mathematical operations | `+`, `-`, `/`, `*`, `%`, `**` |\n| Comparators | `===`, `!==`, `==`, `!=`, `\u003c`, `\u003e`, `\u003c=`, `\u003e=` |\n| Logical operations | `\u0026\u0026`, \u003ccode\u003e\u0026#124;\u0026#124;\u003c/code\u003e, `!` |\n| Bitwise operations | `\u0026`, \u003ccode\u003e\u0026#124;\u003c/code\u003e, `^` |\n| Ternary operator | `... ? ... : ...` |\n| Nullish operator | `??` |\n| Variables | `const` and `let` declarations. Assignments. |\n| Conditional | [`if...else`] statement. |\n| Loops | [`while`] and [`for...of`] statements. |\n| [`JSON`] | `JSON.parse()` and `JSON.stringify()`. |\n| [`Math`] | [`Math.random()`], [`Math.min()`], [`Math.max()`], [`Math.floor()`], [`Math.ceil()`] and [`Math.round()`]. |\n| [Spread operator] (`...`) | Spread syntax for arrays, objects, and parameters. |\n| Global functions | [`parseFloat`], [`parseInt`], [`isNaN`] and [`isFinite`]. |\n\n# Coming soon...\n\n| Status | Feature | Notes |\n|--------|---------|-------|\n| :sweat: In Progress | global [`this`] | Reference to the global object. |\n| :sweat: In Progress | [`Array.isArray()`] | Determines whether the passed value is an Array. |\n| :sweat: In Progress | [`+=`] operator | Addition assignment. |\n| :hourglass_flowing_sand: To-Do | [`Array.from()`] | Creates a copy of an iterable or array-like object. |\n| :hourglass_flowing_sand: To-Do | [`Array.of()`] | Creates an array from the arguments. |\n| :hourglass_flowing_sand: To-Do | Block evaluation | Run a block code and return the block context variables with the values at the end of the execution. |\n\n# Future features\n\n:incoming_envelope: [Vote](http://etc.ch/YzCv) what's coming on! :bulb: or [Suggest](https://github.com/danielduarte/es-eval/issues/new) your ideas.\n\n| Feature | Notes |\n|---------|-------|\n| Browser support | |\n| `for in` loop | |\n| `for (;;)` loop | |\n| `do ... while` loop | |\n| Destructuring | |\n| *And a lot more!...* | |\n\n# How it works?\n\n- It never executes user code passing it to JS engine (no `eval()`, no `new Function(...)`, no `vm`, no other third party engines), making sure the evaluation is safe.\n- No access to require/import modules.\n- No access to OS features like file system, network, etc.\n- No access to global objects.\n- All user code is parsed to an AST and analyzed step by step, representing the code statements and functions in own components. No native `function`s are created with the user input.\n- All access to global objects is emulated and there's no real access to natives.\n- Standard ECMAScript features are implemented and not delegated to the underlying engine.\n\n# What is this for\n\n:white_check_mark: Evaluate user input expressions safely\n\n:white_check_mark: Easily provide a way to enter and evaluate custom conditions\n\n:white_check_mark: Embed JS expressions in template engines\n\n:white_check_mark: Parse custom JS functions once and evaluate them many times\n\n:white_check_mark: Create expressions with context values, including objects and arrays\n\n\n# What is this **NOT** for\n\n:no_entry: Create entire applications\n\n:no_entry: Replace V8, or other JS engines\n\n\n[halting problem]:   https://en.wikipedia.org/wiki/Halting_problem\n[`this`]:            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this\n[`+=`]:              https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition_assignment\n[`Array.isArray()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray\n[`Array.from()`]:    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from\n[`Array.of()`]:      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of\n[`if...else`]:       https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\n[`while`]:           https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\n[`for...of`]:        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of\n[`JSON`]:            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON\n[`Math`]:            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math\n[`Math.random()`]:   https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random\n[`Math.min()`]:      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min\n[`Math.max()`]:      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max\n[`Math.floor()`]:    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor\n[`Math.ceil()`]:     https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil\n[`Math.round()`]:    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round\n[Spread operator]:   https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax\n[`parseFloat`]:      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat\n[`parseInt`]:        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt\n[`isNaN`]:           https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN\n[`isFinite`]:        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielduarte%2Fes-eval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielduarte%2Fes-eval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielduarte%2Fes-eval/lists"}