# Code

Run your own JavaScript in a step to reshape data the other apps can’t.

## Do things in Code

Add a **Code** step. Choose the row to see all its fields.

- [Run Code](https://docs.gorunner.io/apps/code#fields-f-run-code): Write JavaScript to transform data.

Map values under **Inputs**, read them as `inputs`, and `return` what the next steps should get:

```javascript
const name = inputs.name || "world";
return { greeting: `Hello, ${name}!` };
```

Later steps read what you return as `{{steps.<name>.result}}`. You can also read `trigger`, `steps`, `$vars`, `$now` and `$today`, and write to the log with `console.log`.

### Versions

A new Code step is on 2.0.0, which replaces nothing inside the code: never write `{{ }}` there. It is refused when you check or publish. Older steps stay on 1.0.0, which pastes each `{{ }}` into the program text before it runs, so whoever calls the trigger can change the program. Upgrade one with **Upgrade to 2.0.0** in the step, or [from the API](https://docs.gorunner.io/api/workflows/upgrade-code-step).

JavaScript that doesn’t parse saves as a draft, but publishing it is refused with `code_syntax_error` and the line. A 1.0.0 step that holds `{{ }}` is checked only when it runs.

`Intl.NumberFormat` and `Intl.DateTimeFormat`, and `toLocaleString` on numbers and dates, format in about 1,100 locales, as Node writes them: `new Intl.DateTimeFormat("en-CA").format(date)` gives a date such as `2026-10-26`. A locale GoRunner doesn’t have falls back as in Node, to its language, then `en-US`. See [Expressions](https://docs.gorunner.io/build/expressions#numbers-and-dates).

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

## Limits

- There is no `npm`, `require`, `import` or network. To call an API, use an **HTTP Request** step and map its reply in as an input.
- A Code step stops after 30 seconds, or sooner if you set a shorter **Timeout** (under **Error handling**). It may use up to 256 MB of memory. On a self-hosted installation, `SCRIPT_MEMORY_LIMIT_MB` changes that.
- Code is at most 256 KB, and the log keeps 1 MB. A step may pass on at most 16 MB, so a larger result fails the step. On a self-hosted installation, `MAX_STEP_OUTPUT_BYTES` raises that, up to the 64 MB a Code step can return.
- In a product that embeds GoRunner, the provider’s **Code step** switch can remove this app.
- Whole numbers longer than 15 digits lose their last digits. Keep long IDs as text.

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, Code is `pieceId: "code"` with `actionId: "run_code"`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

It computes from its inputs only (`pure`). See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### Code › Run Code

Write JavaScript to transform data. Read mapped values as `inputs.\<name>`, earlier steps as `steps.\<name>`, and `return` the result.

- **Inputs · Optional**: Name values from earlier steps, such as `email` = `{{trigger.body.email}}`, then read them in the code as `inputs.email`.
- **Code · Required**: JavaScript, run as an async function. Read `inputs.\<name>`, `steps.\<name>` and `trigger`, then `return` this step's output. No network access: put an HTTP Request step before this one. Default: ```javascript
// Read Inputs as inputs.<name>, earlier steps as steps.<name>, the trigger as trigger.
// Whatever you return is this step's result.

const name = inputs.name || "world";

return {
 greeting: `Hello, ${name}!`,
 at: $now,
};
```

Source: https://docs.gorunner.io/apps/code
