Available in Retrobatch Pro 1.1.

The JavaScript node allows you to run a JavaScript function when your workflow starts, each time an image is processed by the node, and at workflow end. Below are the function signatures of the three methods you can implement

function workflowStart(document, jsnode) {


function processAsset(document, jsnode, asset) {


function workflowEnd(document, jsnode) {


As an example, if you wanted to reject any images that have a file name which starts with the number "1", you would implement the processAsset function as follows:

function processAsset(document, jsnode, asset) {

    if (asset.outputFileName().startsWith("1")) {
        return false;

    return true;

Returning true from the processAsset function tells Retrobatch that the image passed in should go to the next node. If you return false, then it effectively filters out the given image. If no value is returned, it's treated as true.

JavaScript Cocoa Bridge

The JavaScript runtime Retrobatch uses allows you to also use any classes from Apple's Cocoa frameworks. This means you can mix together Core Image filters, download data from URLs, or any number of things.


Writing classifications to a file.

If you have a workflow with a Classification node (available on MacOS 10.13 or later) prior to a JavaScript node, you can use the following example to write out all the generated classifications to a file.

// Create a global variable to store our classifications in
var classifications = "";

function processAsset(document, jsnode, asset) {

    var s = asset.outputFileName() + ": " + asset.topClassification()

    // add to our global list of classifications
    classifications = classifications + "\n" + s

    // return true so that image continues to be processed through the workflow
    return true;

function workflowEnd(document, jsnode) {
    // Put it into a class we can write to with cocoa.
    var s = NSString.stringWithString(classifications)

    // Ask our node what the first write folder is.
    var outFolder = jsnode.firstWriteFolderPath();

    // Write it to disk!
    s.writeToFile_atomically(outFolder + "classifications.txt", true);

Printing out useful information about an image:

function processAsset(document, jsnode, asset) {

    console.log("\nInfo for " + asset.outputFileName());
    console.log("Bits per channel/component: " + asset.bitsPerComponent());
    console.log("Color model: " + asset.colorModel());
    console.log("Color profile name: " + asset.colorProfileName());
    console.log("DPI: " + asset.dpi());
    console.log("Path: " + asset.filePath());
    console.log("URL: " + asset.fileURL());
    console.log("Has alpha: " + asset.hasAlphaChannel());
    console.log("Width: " + asset.imageWidth());
    console.log("Height: " + asset.imageHeight());
    console.log("Megapixels: " + asset.imageMegaPixels());
    console.log("File type: " + asset.imageFileType());
    console.log("UTI: " + asset.uti());

    console.log("Retrobatch ID: " + asset.uniqueID());

    return true;

Applying a Core Image filter

For a list of available filters, visit Apple's Core Image Filter Reference

function processAsset(document, jsnode, asset) {

    var center = CIVector.vectorWithX_Y_(asset.imageWidth() / 2, asset.imageHeight() / 2);

    var filterParams = {
        inputWidth: 5,
        inputSharpness: .5,
        inputCenter: center,

    var image = asset.CIImage()
    image = image.imageByApplyingFilter_withInputParameters_("CICircularScreen", filterParams);

    return true;