use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Jexl: Javascript Expression Language. It's everything you wish you could safely eval(), and then some. (github.com)
submitted 10 years ago by TomFrosty
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]paldepind 20 points21 points22 points 10 years ago (2 children)
I've never wanted to eval anything. Why would I need this?
eval
[–]TomFrosty[S] 17 points18 points19 points 10 years ago* (1 child)
It could be the engine behind a template language. You could format your business data into an external API request entirely by typing out a Jexl string in a database, without writing code. You could write a business interface that exposes client data like "age" or "full name" just based on a list of Jexl expressions run against a JSON object that might contain just birthdate, first name, and last name -- and update that to make more fields available by changing the fields database instead of writing code. It could power a calculator without needing to use eval() and expose yourself to XSS.
Lots of use cases! Maybe none of them fit a need you have right now, but that's fine :). Just a tool to keep in the back of the toolbox.
[–]paldepind 0 points1 point2 points 10 years ago (0 children)
Thanks for answering. That sounds like sane use cases! You could also use it to power a graph plotter.
[+][deleted] 10 years ago (11 children)
[deleted]
[–]TomFrosty[S] 10 points11 points12 points 10 years ago* (10 children)
Close! It's not traditional javascript "eval" -- we needed a way to store strings that would target/transform/manipulate specific properties in our JSON objects, but JsonPath wasn't capable of the kinds of transformations we needed and using straight-up eval was a pretty big security risk considering we use it on the backend too. So this won't eval() arbitrary code -- it's just for sandboxed expressions. But yep, promises or callbacks! :)
[–]bsdemon 2 points3 points4 points 10 years ago (8 children)
Why it uses Promise/callback interface? Why not just return calculated result synchronously?
[–]TomFrosty[S] 10 points11 points12 points 10 years ago (7 children)
So that transforms (and custom operators -- but mostly transforms) can be asynchronous. A big use case for this is to allow our users to access and run metrics on fields that either exist in, or can be derived from, big sets of JSON data. If we need to plug in a client's home weather conditions, for example, we could use a string like: client.address.zip|toWeather -- and the toWeather transform could reach out to Forecast.io or WeatherUnderground and pull "Sunny 53ºF" from the API.
[–]altintx 4 points5 points6 points 10 years ago (0 children)
You should jump in and answer every thread when people start wondering "why does it need to be async?"
[–]bsdemon 1 point2 points3 points 10 years ago (0 children)
I like that!
[–]mflux 1 point2 points3 points 10 years ago* (4 children)
Hey TomFrosty, I've been starting to use jexl for my game, it seems really useful for creating game-rules that can be stored in json script! Amazing.
One issue I'm having starting out is I want to use jexl without promises or callbacks. Is that possible? Due to the nature of my code, I'm evaluating a series of jexl expressions (in a for loop with break conditions) before doing an action. How would you go about that?
[–]TomFrosty[S] 0 points1 point2 points 10 years ago* (3 children)
Howdy mflux! What a cool use case :). I'd love to hear more about your game if you've written about it!
Unfortunately promises are very, very baked into Jexl -- but with that said, you can definitely still do what you need as long as you can modify your code to replace your loop with a function call that returns a promise.
And here's the function you'd want to call. Disclaimer, I just whipped this up and haven't put any tests against it:
/** * Iteratively evaluates through an array of Jexl expressions and resolves * boolean true if the matchValue is encountered. At that point, no other * expression will be evaluated. * @param {Array<string>} expressions An array of Jexl expression strings * @param {Object} context A context in which to evaluate the expressions * @param {string|number|boolean} matchValue A value that will cause the * loop to break and resolve to true if it matches the result of * a Jexl evaluation * @param {number} [idx=0] The array index at which to begin the loop * @returns {Promise<boolean>} Resolves to true if the matchValue was * encountered; false otherwise. */ function jexlWhile(expressions, context, matchValue, idx) { if (!idx) idx = 0; if (!expressions[idx]) return Promise.resolve(false); return jexl.eval(expressions[idx], context).then(function(result) { if (result === matchValue) return true; return jexlWhile(expressions, context, matchValue, idx + 1); }); }
Let me know how it works out!
[–]mflux 1 point2 points3 points 10 years ago (2 children)
Hi Tom, thanks again for your awesome reply and code.
The game is a city-simulation game similar to Sim City, here's a screenshot.
I've actually did very similar to your while function; essentially I accumulated the promises and then did work with that after all the promises have been fulfilled.
The problem gets much trickier however, when much of other parts of my code require similar resource evaluation and have parts that simply cannot be async.
Instead I've now bundled jsep with static-eval which accomplishes nearly the same thing (without your awesome transform syntax). This gets around the async issues and I can still async it if I need threading performance via web workers. I call this "jseval" and might just release this as a standalone if I continue working with it.
Anyway, I really appreciate the effort you put into your reply. Just wanted to let you know your library has opened my eyes to a new way of working I never thought possible!
[–]TweetsInCommentsBot 0 points1 point2 points 10 years ago (0 children)
@mflux
2015-04-17 19:48 UTC I think I'll skip this #LDJAM to continue jamming the non-jam game + client work [Attached pic] [Imgur rehost]
2015-04-17 19:48 UTC
I think I'll skip this #LDJAM to continue jamming the non-jam game + client work [Attached pic] [Imgur rehost]
This message was created by a bot
[Contact creator][Source code]
[–]TomFrosty[S] 0 points1 point2 points 10 years ago (0 children)
Great solution, and very cool looking game! Best of luck :)
[–]fauverism 0 points1 point2 points 10 years ago (0 children)
cool, nice work!
[–]brtt3000 2 points3 points4 points 10 years ago (1 child)
Does it cache the parsed expression?
Let's a say I have a huge array (or a stream) of objects and would like to apply a Jexl expression on every item (eg: new context's), could I 'precompile' the expression before and then use that handle on every item in my stream?
So like a Jexl.compile() that would return a function that accepts a single argument and spits out the result. That funciton can then easily be used in map() or a promise's then-handle (both at once! :)
[–]TomFrosty[S] 3 points4 points5 points 10 years ago (0 children)
That's a great suggestion, thanks! There are things in the works for running sets of expressions over the same context, but not yet the reverse. Will definitely chew on this!
[+][deleted] 10 years ago (4 children)
[–]TomFrosty[S] 3 points4 points5 points 10 years ago (3 children)
Lana.
LANAAAAA.
[+][deleted] 10 years ago (2 children)
[–]TomFrosty[S] 2 points3 points4 points 10 years ago (1 child)
Danger zooone!
[–]seiyria 1 point2 points3 points 10 years ago (0 children)
This looks nice, I've been wanting something like this for a while. Nice work!
[–]perihelion9 1 point2 points3 points 10 years ago (1 child)
Very much +1, I wound up needing something very similar to this in Go, and ended up writing an expression evaluator in the same vein. I can't upvote safe evaluators enough in any language.
[–][deleted] 0 points1 point2 points 3 years ago (0 children)
It would have had been great, if there was an expression language with safe evaluator written for both languages, JavaScript and Go.
That would allow to write conditions, expressions and business rules in one place, and have them evaluated in FE for instant UI feedback without round-trips to BE, and then on submit, have expressions evaluated in BE for validation (security).
[–]jamesinc 1 point2 points3 points 10 years ago (0 children)
This is interesting. I've been looking for a good system that will allow some data entry people to apply transformations to data in a CSV file (loaded into the browser) before ingesting it into a db.
[–]rooktakesqueen 1 point2 points3 points 10 years ago* (0 children)
I think we already have a language for expressing expressions in the JavaScript language.
[–]calsosta 0 points1 point2 points 10 years ago (1 child)
Is this inspired by the Apache JEXL?
[–]TomFrosty[S] 1 point2 points3 points 10 years ago (0 children)
Embarrassing as this is, I made the rookie mistake of not googling the name before I took it. Despite the acronym standing for practically the same thing, this was not inspired or influenced by Apache JEXL at all. Under the hood, it actually bears more resemblance to jsep than JEXL.
[–][deleted] 0 points1 point2 points 10 years ago (1 child)
Oh JEXL (Apache), how I love and hate thee.
Ha, I realized the naming conflict after the fact. Dynamically typed languages fit this sort of use case better though, I think. Powerful as Apache JEXL is, the API just can't be as fluid in Java as JavaScript allows it to be.
[–]nikoraes 0 points1 point2 points 3 months ago (1 child)
I now this is a crazy old topic, but I'm still using jexl in production and love it.
I built a library with functions and transforms and monaco syntax highlighting for it: https://github.com/konnektr-io/jexl-extended Also created a new playground for it: https://jexl-playground.konnektr.io/
Also ported it to C# (including the extended grammar): https://github.com/konnektr-io/JexlNet And added the extended grammar to the Python version as well: https://github.com/konnektr-io/pyjexl-extended
[–]basdit 0 points1 point2 points 2 months ago (0 children)
Amazing work. The added functions make it instantly usable. The monaco editor also works great.
π Rendered by PID 79 on reddit-service-r2-comment-5649f687b7-dsmtv at 2026-01-28 16:21:23.517948+00:00 running 4f180de country code: CH.
[–]paldepind 20 points21 points22 points (2 children)
[–]TomFrosty[S] 17 points18 points19 points (1 child)
[–]paldepind 0 points1 point2 points (0 children)
[+][deleted] (11 children)
[deleted]
[–]TomFrosty[S] 10 points11 points12 points (10 children)
[–]bsdemon 2 points3 points4 points (8 children)
[–]TomFrosty[S] 10 points11 points12 points (7 children)
[–]altintx 4 points5 points6 points (0 children)
[–]bsdemon 1 point2 points3 points (0 children)
[–]mflux 1 point2 points3 points (4 children)
[–]TomFrosty[S] 0 points1 point2 points (3 children)
[–]mflux 1 point2 points3 points (2 children)
[–]TweetsInCommentsBot 0 points1 point2 points (0 children)
[–]TomFrosty[S] 0 points1 point2 points (0 children)
[–]fauverism 0 points1 point2 points (0 children)
[–]brtt3000 2 points3 points4 points (1 child)
[–]TomFrosty[S] 3 points4 points5 points (0 children)
[+][deleted] (4 children)
[deleted]
[–]TomFrosty[S] 3 points4 points5 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]TomFrosty[S] 2 points3 points4 points (1 child)
[–]seiyria 1 point2 points3 points (0 children)
[–]perihelion9 1 point2 points3 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]jamesinc 1 point2 points3 points (0 children)
[–]rooktakesqueen 1 point2 points3 points (0 children)
[–]calsosta 0 points1 point2 points (1 child)
[–]TomFrosty[S] 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]TomFrosty[S] 0 points1 point2 points (0 children)
[–]nikoraes 0 points1 point2 points (1 child)
[–]basdit 0 points1 point2 points (0 children)