Apps Script V8 Runtime Is Here! What Does That Mean?

In February 2020, Google announced the launch of the V8 runtime for Apps Script, which is the same runtime environment that powers Chrome. It allows us to take advantage of all the modern JavaScript features.

A runtime environment is the engine that interprets your code and executes the instructions.

Historically, Apps Script used a runtime environment called Rhino, which locked Apps Script to an older version of JavaScript that excluded modern JavaScript features.

But no more!

In this guide, we’ll explore the basics of the new V8 runtime, highlighting the features relevant for beginner-to-intermediate level Apps Script users.

Enabling The Apps Script V8 Runtime

When you open the Apps Script editor, you’ll see a yellow notification bar at the top of your editor window prompting you to enable V8:

Enable V8 runtime in Apps Script

If you don’t see this notification, you can select Run > Enable new Apps Script runtime powered by V8

Enable V8 runtime in Apps Script

Save your script to complete the enabling process.

If you need to return to the old version (in the unlikely scenario your script isn’t compatible with the new V8 runtime) then you can switch back to the old Rhino runtime editor.

Select Run > Disable new Apps Script powered by V8.


New Logging In The Apps Script V8 Runtime

The new V8 runtime logger shows both the Logger.log and console.log results for the most recent execution under the View > Logs menu.

Previously the console results were only accessible via the Stackdriver Logging service.

Here’s an example showing the Logger and console syntax (notice Logger is capitalized and console is not):

function loggerExample() {
  Logger.log("Hello, world from Logger.log!");
  console.log("Hello, world from console.log!")
}

The output in our logger window (accessed via View > Logs) shows both of these results:

Logger and console logs in V8


Modern JavaScript Features

There are a lot of exciting new features available with modern JavaScript. They look strange at first but don’t panic!

There’s no need to start using them all immediately.

Just keep doing what you’re doing, writing your scripts and when you get a chance, try out one of the new features. See if you can incorporate it in your code and you’ll gradually find ways to use them.

Here are the new V8 features in a vague order of ascending difficulty:

Multi-line comments

We can now create multi-line strings more easily by using a back tick syntax:

// new V8 method
const newString = `This is how we do 
multi-line strings now.`;

This is the same syntax as template literals and it greatly simplifies creating multi-line strings.

Previously each string was restricted to a single line. To make multi-line comments we had to use a plus-sign to join them together.

// old method
const oldString = 'This is how we used\n'
+ 'to do multi-line strings.'; 

Default Parameters

The Apps Script V8 runtime lets us now specify default values for parameters in the function definition.

In this example, the function addNumbers simply logs the value of x + y.

If we don’t tell the function what the values of x and y are, it uses the defaults we’ve set (so x is 1 and y is 2).

function addNumbers(x = 1, y = 2) {
  console.log(x + y);
}

When we run this function, the result in the Logger is 3.

What’s happening is that the function assigns the default values to x and y since we don’t specify values for x and y anywhere else in the function.

let Keyword

The let statement declares a variable that operates locally within a block.

Consider this fragment of code, which uses the let keyword to define x and assign it the variable of 1. Inside the block, denoted by the curly brackets {…}, x is redefined and re-assigned to the value of 2.

let x = 1;
  
{
  let x = 2;
  console.log(x); // output of 2 in the logs
}
  
console.log(x); // output of 1 in the logs

The output of this in the logs is the values 2 and 1, because the second console.log is outside the block, so x has the value of 1.

Note, compare this with using the var keyword:

var x = 1;
  
{
  var x = 2;
  console.log(x); // output of 2 in the logs
}
  
console.log(x); // output of 2 in the logs

Both log results give the output of 2, because the value of x is reassigned to 2 and this applies outside the block because we’re using the var keyword. (Variables declared with var keyword in non-strict mode do not have block scope.)

const Keyword

The const keyword declares a variable, called a constant, whose value can’t be changed. Constants are block scoped like the let variable example above.

For example, this code:

const x = 1;
x = 2; 
console.log(x);

gives an error when we run it because we’re not allowed to reassign the value of a constant once it’s been declared:

const keyword error

Similarly, we can’t declare a const keyword without also assigning it a value. So this code:

const x;

also gives an error when we try to save our script file:

Apps Script V8 runtime const error message

Spread syntax

Suppose we have the following array of data:

const arr = [[1,2],[3.4],[5,6]];

It’s an array of arrays, so it’s exactly the format of the data we get from our Sheets when we use the getRange().getValues() method.

Sometimes we want to flatten arrays, so we can loop over all the elements. Well, in V8, we can use the spread operator (three dots … ), like so:

const flatArr = [].concat(...arr);

This results in a new array: [1,2,3,4,5,6]

Template Literals

Template literals are a way to embed expressions into strings to create more complex statements.

One example of template literals is to embed expressions within normal strings like this:

let firstName = 'Ben';
let lastName = 'Collins';
console.log(`Full name is ${firstName} ${lastName}`);

The logs show “Full name is Ben Collins”

In this case, we embed a placeholder between the back ticks, denoted by the dollar sign with curly brackets ${ some_variable }, which gets passed to the function for evaluation.

The multi-line strings described above are another example of template literals.

Arrow Functions

Arrow functions provide a compact way of writing functions.

Arrow Function Example 1

Here’s a very simple example:

const double = x => x * 2;

This expression creates a function called double, which takes an input x and returns x multiplied by 2.

This is functionally equivalent to the long-hand function:

function double(x) {
  return x * 2;
}

If we call either of these examples and pass in the value 10, we’ll get the answer 20 back.

Arrow Function Example 2

In the same vein, here’s another arrow function, this time a little more advanced.

Firstly, define an array of numbers from 1 to 10:

const arr = [1,2,3,4,5,6,7,8,9.10];

This arrow function will create a new array, called evenArr, consisting of only the even numbers.

const evenArr = arr.filter(el => (el % 2 === 0));
console.log(evenArr);

The filter only returns values that pass the conditional test: (el % 2 === 0) which translates as remainder is 0 when dividing by 2 i.e. the even numbers.

The output in the logs is [2,4,6,8]:

Apps Script V8 runtime arrow function logs

Other Advanced Features

There are more advanced features in V8 that are not covered in this post, including:

I’m still exploring them and will create resources for them in the future.


Migrating Scripts To Apps Script V8 Runtime

The majority of scripts should run in the new V8 runtime environment without any problems. In all likelihood, the only adjustment you’ll make is to enable the new V8 runtime in the first place.

However, there are some incompatibilities that may cause your script to fail or behave differently.

But for beginner to intermediate Apps Scripters, writing relatively simple scripts to automate workflows in G Suite, it’s unlikely that you’ll have any problems.

You can read more about migrating scripts to the V8 runtime and incompatibilities in the detailed documentation from Google.


Other Apps Script V8 Runtime Resources

V8 Runtime Overview

ES 6 Features for Google Apps Script: Template Literals

ES6 Features for Google Apps Script: Arrow Functions

Here’s a good explanation of the V8 runtime from Digital Inspiration

The new V8 runtime offers significant performance improvements over the old Rhino editor. Your code will run much, much faster! Here’s a deep dive: Benchmark: Loop for Array Processing using Google Apps Script with V8

9 thoughts on “Apps Script V8 Runtime Is Here! What Does That Mean?”

  1. Hi ben, thanks for sharing. I understood better the features that V8 brings.

    I think I can use arrow funcitons can be useful when I need to create a function inside other function (in-line functions).

    I think I can use the default parameters to test some functions instead of creating test functions.

    I don’t know if it’s me, but console.log and Logger.log take more time in V8 than in Rhino.

    I know this things would be imrpoved but Google says the script will run faster and some things still are faster in Rhino.

    1. Agh, indeed! Thank you for this idea, very nice (using default parameters to test functions instead of creating test functions).

  2. I’ve too have been testing out the V8 and agree with the individual above about the logging taking longer.
    One of the things I do frequently is execute stored procedures on an MS SQLServer database with a JDBC connection. So I spent an afternoon running this through simple queries and simple stored proc calls. Unfortunately, I discovered an issue with a procedure that runs fine in the Rhino but simply times out in the V8. I’m not sure if that is related to the logging or what. The query has a number or table joins. I did an exercise where I added each join and bits of the query that it returned. It crapped out when I joined more than seven tables one of which was in another database. I frequently am pulling data from two different databases. They query itself is not pulling tons of data, so it was a bit frustrating. I ended up building a temp table on the server and writing a proc to populate and refresh that temp table on the server and running that periodically and now just have the Apps Script pulling from the newly created temp table instead of having the Apps Script running the one query that used to pull the data in one shot.

    Thanks for your post, I frequently find the info you share about Apps Script very helpful.

  3. Hi Ben,
    I am a true follower of your guides and tips. I believe the new additions make a lot of sense, but I am currently having issues in a specific program that I have written in Rhino (works perfectly) but when migrated to V8 it crashes every time and the error code doesn’t give me as much information to pinpoint where it is breaking regarding the incompatibilities list that google gave.

    Do you think you could give me a hand with this?

    The error pops-up when running main() function.
    I honestly have I get the error “Exception: Invalid argument: cells[5][1] (line 103, file “Code”)”

    https://docs.google.com/spreadsheets/d/1gJRUROhc9Cis23he2dcmrGJrvr80Drt5q–3l9KvVM8/edit?usp=sharing

  4. Hi,

    Fristly, thank you for this post!

    I found something really interesting in GAS inheritance. The parent class and the child class both have to be in the same ‘.gs’ file in a GAS project in order to make inheritance function properly.

    Well, Google (https://developers.google.com/apps-script/guides/v8-runtime) doesn’t give any example with the use of the word ‘extends’, simply gives an example of ‘class Rectangle’.

  5. It is possible to prevent V8 script to be executate and you copy a file. I have already an old Rhino script in a file and I have desactivated V8… but when I copy the file, the V8 is activated by default and my script don’t work for users!!! Do you have
    Any solutions? A script to desactivate V8???

  6. Hi Ben,

    Thanks for this it has really helped explain the V8 changes. I have been using template literals extensively as soon as I read about their availability, it’s a shame the editor doesn’t format them well.

    Have you any experience using the spread operator? I have tested a simple html page using an array of data to generate an array of option elements to be appended to a select element. I am then using the parent.append() method to append the options array to the select element. I wasn’t familiar with the spread operator until using the append method and was thrilled when sticking 3 dots in front of the array name made the whole thing work and my options from the array appear in the select drop down.

    However when I tried this in Google Apps Script it simply will not populate my select boxes with the options from the array.

    Have you tried to use the spread operator in GAS yet? Can it be used in that way?

  7. Hi Ben,

    Could you do a execution time comparison of V8 Runtime and Rhino for accessing user/script properties. The execution time PropertyService.getUserProperties().getProperty(“KEY”) for Rhino is averaging around 0.05 second while for V8 its 0.5 second (i.e 10 times higher for V8).

Leave a Reply

Your email address will not be published. Required fields are marked *