How to convert any JavaScript library to work with vRO [CB10105]

vRO doesn’t use a regular JavaScript engine such as the ones that run in the browser or server side Node.js . It uses the Rhino engine, which is based on Java, and as such it has a lot of quirky differences with regular JavaScript.

There are quite a few differences in syntax and behavior compared to regular JS, so it can be expected that a lot of things that you think should work, will not work inside vRO.


Some of the limitations that vRO JavaScript has:

  • JS feature basically stop at ES5, but some features of ES5 aren’t even implemented.
  • Not all of the API is available inside vRO, and some objects, methods or functions have been replaced with an equivalent (Console.log is equivalent to System.log in vRO)
  • You can’t normally use external JS libraries such as axios, jQuery, lodash, etc.

If you want to use an external library inside VRO, there are a few things to consider, but these are the most important:

  • The JS version that the library is/depends on.
  • The APIs and JS features that the library depends on.

If your library is based on pre-ES5 JavaScript and does not use any special, browser-specific or node.js specific APIs, it should work out of the box inside vRO.


If not, then you can try a few things to try to get it to work inside vRO:

  • Use a transpiler (and bundler if you need) (such as Babel+Webpack, SWC, Esbuild, to name just a few) to downgrade the source code of the library you want to use into an older version of JS into a single JS file.
  • You might need to use polyfills if you use some browser or Node.js APIs because they will not work inside VRO even when transpiled and downgraded.
  • Put the resulting JS code into the same vRO workflow/action that you want to use it in and use it directly (I don’t recommend this, as it can become a mess quite fast and is unreadable)
  • Put the resulting JS code into a vRO resource element, then inside your vRO workflow/action , get the content of this resource element (it will be a string at this point) and use the eval() or the Function constructor to parse and evaluate the library code. It will then be available to use inside the rest of the workflow/action. (I recommend this method, since it is the least error prone, takes 1-3 lines of code only and is more readable)
  • You could do the same thing, but additionally split the library code into as many smaller working modules/objects/functions as you want to have better performance and potentially work around vRO’s limitations when working with huge files.

This is what worked for me in general, but I can’t guarantee that it will work in all cases. Because of the bizarre nature of the Rhino engine and limitations of vRO, you could run into other problems or limitations and won’t be able to use the JS library that you want to use. For example, if your library code is too big, vRO will not be able to use it as it will run out of memory, or the workflow/action will crash, or it will just stop evaluating the library code midway and be useless.


There are 2 other ways to use external libraries inside vRO workflows/actions, but they don’t use the normal vRO engine. Just keep in mind that using this way, you cannot directly access all of the vRO APIs such as resource elements, plugins ,etc. So it has some limitations :

Credits to Olivier Fortier for this lucid explanation.


One Comment

  1. Here’s a way I found that is a little bit tricky. Let’s say you want to use lodash.js. This version :

    You create an action, let’s call it lodashLibrary which return a type Properties.
    That code will populate the global object with a root function.
    lodash declare a variable called _
    So you have to export this object outside with this trick :
    You create an empty object outside the library so put this at the beginning of your script :
    var global = {};
    Then you copy paste the js code which have to be Rhino compatible (ES5).
    Libraries in js tend to be wrapped in something similar to
    (function () {
    // here you add this line at the end of the imported function:
    global = root; // root is the object that lodash export

    And you return that object with this line put at the end of the script :
    return global._;

    And in your action you call it in your code that way :

    var _ = _ || System.getModule(“the.path.of.your.action”).lodashLibrary();

    and then you can use lodash !

    Liked by 1 person


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s