---
title: "Tutorial: your first code step in a workflow"
description: "Add a Run function step with JavaScript written in the step, build an order summary from the event, test the code for real, and use its result in the next step."
canonical: "https://docs.workflow-suite.app/tutorial-your-first-code-step"
---

# Tutorial: your first code step

Most workflows never need code. When they do, a **Run function** step runs a few lines of JavaScript in a sandbox and hands the result to the next step. In this tutorial you add a code step to an order workflow that turns the order into one summary line, test the code on its own, and use the line in a Slack message.

If you followed [Tutorial: tag high-value orders and tell Slack](https://docs.workflow-suite.app/tutorial-tag-high-value-orders-and-tell-slack.md), continue in that workflow. Any workflow with the trigger **Order created** works.

## 1. Add the step

1. Press the **+** after the last step. In **Add a step**, under **Code and requests**, pick **Run function**.
2. Set **Name** to `Build the summary`.
3. Under **Code** choose **Write the code in this step**. A JavaScript editor appears with a small example.

## 2. Write the code

Replace the example with this:

```javascript
export default async function (input, ctx) {
  // The order that started the workflow
  const order = input.event.payload
  const items = (order.line_items ?? [])
    .map((line) => `${line.quantity} x ${line.title}`)
    .join(", ")
  const summary = `Order ${order.name}: ${order.total_price} ${order.currency} (${items})`
  ctx.log("summary", summary)
  return { summary, itemCount: (order.line_items ?? []).length }
}
```

What it does:

- `input.event.payload` is the order, exactly as the trigger delivered it. `input.steps` holds what earlier steps returned, and any fields you put into **Input (JSON)** arrive next to them.
- `ctx.log(...)` writes a line into the run logs. It is the easiest way to see what the code saw.
- Whatever the function **returns** becomes the step's output. Later steps read it as `steps.<step id>.output.summary`.

![The Run function side panel: Name Build the summary, Code set to Write the code in this step, and a JavaScript editor holding an export default async function that builds an order summary from input.event.payload](https://cdn-dev.eu.codecreationlabs.cloud/crm-tool/uploads/SjJ78gKLnLlocopCui3Cs62dJbGZ7F1n/675d613ccea5acff.png)
*Code in the step. Save as function turns it into a saved function you can reuse in other workflows.*

## 3. Test the code on its own

1. At the top of the side panel select **Test this step**. The result says **Previewed**: in a preview, code does not run, because nobody can know what it would change.
2. Select **Change** and pick **Run for real** in the Test panel. Back in the side panel the button now reads **Test for real**.
3. Select **Test for real** and confirm. This code only reads the event and returns text, so nothing in the store changes.

![The dialog Test this step for real? explaining that the step and every step before it run for real, with Cancel and Test for real buttons](https://cdn-dev.eu.codecreationlabs.cloud/crm-tool/uploads/SjJ78gKLnLlocopCui3Cs62dJbGZ7F1n/e6d86ade896b0c8a.png)
*The confirmation before a real test. Read it: every step the tested step depends on runs for real too.*

The result turns to **Succeeded** and shows the returned object: `summary` with the order line and `itemCount`.

![The Run function side panel after Test for real: Succeeded, 289 ms, and the output steps.function_1.output with summary Order #1042: 1250.00 USD (1 x Aviator sunglasses, 1 x Leather weekender bag) and itemCount 2](https://cdn-dev.eu.codecreationlabs.cloud/crm-tool/uploads/SjJ78gKLnLlocopCui3Cs62dJbGZ7F1n/2a03ce4d2ec2e7bf.png)
*The code ran against the sample order and returned the summary line.*

> [!NOTE]
> The step id is shown at the bottom of the side panel, for example `function_1`. Later steps read this step's result as `steps.function_1.output.summary`. The variable picker on any field lists it after a test.

## 4. Use the result in the next step

1. Add a **Send Slack message** step after the code step, or open the one you have.
2. In **Message**, press the variable button and pick `steps.function_1.output.summary`, or type:

```
High-value order: {{ steps.function_1.output.summary }}
```

3. **Save**. Run a **Test** of the whole workflow: in a preview the code step is previewed, so the message shows an empty summary. Use **Run for real** on the Test panel when you want the whole chain to run, or trust the real test of step 3.

## Good to know

- A run has 5 seconds and 128 MB. Store data is read and changed with `ctx.shopify.graphql(query, variables)`, other systems are called with `ctx.fetch(url, options)`, up to 20 requests per run. See [Run code and functions](https://docs.workflow-suite.app/run-code.md).
- Secrets are read as `secrets.NAME` and are masked in logs. See [Secrets](https://docs.workflow-suite.app/secrets.md).
- A code step is only previewed in a preview. Its logs and the real output appear under **Run history**, tab **Function runs**.
- Want the same code in several workflows? Select **Save as function** under the editor. The step then runs the saved function, and you edit it in one place under **Functions**.
