Apps Script is a scripting tool built into every Google account. It sits inside Google Sheets (and Docs, Forms, Gmail, and Drive) and lets you automate things that Google Sheets can't do on its own — sending emails when something changes, moving rows between sheets, generating reports on a schedule, and more.

You don't need a coding background to use it. Every tutorial on this site provides working scripts you paste and run. But understanding how Apps Script works — even at a surface level — makes it much easier to adapt those scripts to your situation.

This tutorial explains what Apps Script is, how to access it, and walks you through writing and running your first automation from scratch.

---

What Apps Script Can Do That Google Sheets Can't

Google Sheets handles data storage, formulas, and basic conditional formatting. It can't:

  • Send emails on its own
  • Move data between sheets based on a trigger
  • Run something automatically on a schedule
  • Fill cells based on complex logic that formulas can't express
  • Connect to external services

Apps Script adds all of those capabilities — and it's free, built in, and requires no software installation.

---

How to Open the Apps Script Editor

There are two ways:

From inside a Google Sheet:

  1. Click Extensions in the top menu
  2. Click Apps Script

A new browser tab opens. This is the Apps Script editor.

From Google's Apps Script dashboard:

Go to script.google.com — this shows all the scripts you've created, across all your spreadsheets.

---

What You're Looking At

When the editor opens, you'll see:

  • A file called Code.gs in the left sidebar — this is where you write code
  • A mostly blank editor area with a placeholder function
  • A toolbar at the top with a Run button (the triangle/play icon), a Save button, and a function selector dropdown

The placeholder function looks like this:

Code
function myFunction() {

}

This is a JavaScript function — a named block of code that runs when called. You can have multiple functions in one Code.gs file, each with a different name and a different job.

---

Your First Script: Write a Value Into a Cell

Start with the simplest possible script: one that writes text into a specific cell in your spreadsheet.

Delete everything in the editor and paste this:

Code
function writeToCellA1() {
  // Get the active spreadsheet
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // Get the first sheet tab
  var sheet = spreadsheet.getActiveSheet();

  // Write text into cell A1
  sheet.getRange("A1").setValue("Hello from Apps Script");
}

Plain-English explanation:

  • SpreadsheetApp.getActiveSpreadsheet() — gets the spreadsheet this script is attached to
  • .getActiveSheet() — gets whichever sheet tab is currently active
  • .getRange("A1") — targets cell A1
  • .setValue("Hello from Apps Script") — writes that text into the cell

---

How to Run a Script

  1. Make sure the function name in the dropdown (next to the Run button) says writeToCellA1
  2. Click the Run button (the play icon ▶)

The Authorization Screen

The first time you run any script, Google asks for permission. This happens because the script wants to access your spreadsheet — and Google makes you confirm that's intentional.

  1. A popup appears: "Authorization required." Click Review permissions.
  2. Select your Google account.
  3. You may see a warning: "Google hasn't verified this app." Click Advanced, then Go to [your project name] (unsafe). This warning appears because the script isn't a published app — it's your own code running in your own account. It's safe.
  4. Click Allow.

(unsafe)" visible]

After you click Allow, the script runs. Switch to your spreadsheet tab. Cell A1 should now say "Hello from Apps Script."

---

Three Concepts That Explain Most Scripts

Every Apps Script tutorial on this site uses some combination of these three things. Understanding them makes the code much easier to read.

1. The SpreadsheetApp object

SpreadsheetApp is the entry point for everything related to Google Sheets. From it, you can access spreadsheets, sheets, ranges, and cell values.

The most common starting line:

Code
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

This gets the active sheet in one step. Most scripts start this way.

2. Ranges and values

A range is a cell or group of cells. You get a range with .getRange(), and then you can read from it or write to it.

Read a single cell:

Code
var value = sheet.getRange("B3").getValue();

Read a block of cells (returns a 2D array):

Code
var data = sheet.getRange("A2:D100").getValues();

Write to a cell:

Code
sheet.getRange("C5").setValue("Done");

The pattern is always: get the range, then do something with it.

3. Triggers

A trigger tells Apps Script when to run a function. Without a trigger, scripts only run when you click Run manually.

There are two types:

Simple triggers — named functions that run automatically in response to specific events. The most common:

| Function name | When it runs | |---|---| | onOpen | When the spreadsheet is opened | | onEdit(e) | When any cell is edited |

Simple triggers activate just by naming your function correctly. No setup needed. Important limitation: simple triggers cannot send emails or access other files. If your script needs to do those things, use an installable trigger.

Installable triggers — set up manually through the Triggers menu (the clock icon in the left sidebar). They can run on a time schedule, respond to edit events, and send emails. Every tutorial on this site that involves email uses an installable trigger.

---

A Slightly More Useful Script

Here's a script that reads every row in a sheet and logs rows where a "Status" column says "Review":

Code
function findReviewRows() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();

  for (var i = 1; i < data.length; i++) { // Start at 1 to skip the header row
var rowNumber = i + 1;                 // Row numbers in the sheet start at 1, array index starts at 0
var status = data[i][3];               // Column D = index 3 (A=0, B=1, C=2, D=3)

if (status === "Review") {
  Logger.log("Row " + rowNumber + " needs review");
}
  }
}

To see the output: after running this, click Execution log at the bottom of the editor. You'll see a line for each row where Status = "Review."

This pattern — loop through all rows, check a column value, do something if it matches — is the foundation of most automation scripts.

---

How Column Index Numbers Work

This confuses almost everyone the first time. In Apps Script, column numbers start at 0, not 1:

| Column | Letter | .getValues() index | |--------|--------|----------------------| | First | A | 0 | | Second | B | 1 | | Third | C | 2 | | Fourth | D | 3 |

So data[i][0] is column A, data[i][2] is column C, and so on.

But when you use .getRange() with row and column numbers directly, the count starts at 1:

Code
sheet.getRange(2, 3) // Row 2, Column C (column index 3, not 2)

This inconsistency is a quirk of Apps Script. Once you know it exists, it stops being confusing.

---

What to Build Next

Now that you know how to open the editor, run a script, and understand the basic structure, the natural next steps are:

Every one of those tutorials provides a complete, working script. Now you'll understand what each part does.

Don't want to write the script yourself? Describe what you want to automate and it'll be configured for your sheet. Get it installed