# Variables and data flow

> How data flows between nodes through node output and variables, with scoping rules for subflows and branches.

## What it is

Nodes in Flow don't automatically share data. When a node produces output — like an HTTP response or a computed value — downstream nodes access that output explicitly through expressions. Variables and data flow is how you wire data between nodes and persist values across your process.

There are two ways data moves through a process:

- **Node output** — each node produces output that downstream nodes can reference
- **Variables** — process-level variables you define to store and pass values between nodes

For the full expression grammar, operators, and how to write `$vars` references, see [Expression syntax](expression-syntax.md).

## How it works

![Flow canvas showing Manual Trigger, Script, and Decision nodes with annotated arrows indicating data passed via $vars](https://dev-assets.cms.uipath.com/assets/images/maestro/flow-dataflow-5431c3b7.webp)

### Node output

Every node that produces data makes it available through `$vars.<nodeName>.output`. The node name is auto-assigned based on the node type — for example, the first HTTP Request node is named `httpRequest1`, the second is `httpRequest2`.

You can see a node's variable name in the properties panel when the node is selected.

```javascript
// Access HTTP Request response
$vars.httpRequest1.output.body
$vars.httpRequest1.output.statusCode

// Access Script return value
$vars.script1.output

// Access a second HTTP Request
$vars.httpRequest2.output.body
```

The output structure depends on the node type. Refer to each node's reference page for its specific output shape.

### Variables

Variables are process-level values that persist for the duration of a single execution. You define them in the **Variables** tab of the properties panel.

Each variable has:

- **Name** — how you reference it in expressions (e.g., `$vars.orderTotal`)
- **Type** — String, Number, Boolean, Object, or Array
- **Direction** — input, output, or bidirectional

**When to use variables vs node output:**

- **Node output** fits data that passes from one node to the next. This is the most common pattern.
- **Variables** fit values that must be accessible across the entire process, or values that define inputs and outputs for the process itself.

**Naming variables clearly:** Descriptive, lowercase names with hyphens or camelCase — such as `customerEmail`, `invoiceTotal`, `apiResponse` — remain readable in execution traces over time. Single-letter names and abbreviations lose meaning quickly.

### Trigger inputs

Input variables are owned by their trigger, not by the process. When a trigger fires, its inputs are available as `$vars.<triggerName>.output.<inputName>`:

```javascript
// Access an input defined on a Manual Trigger named "manualTrigger1"
$vars.manualTrigger1.output.userId
```

This applies to all trigger types. If your process has multiple triggers, each trigger owns its own inputs — downstream nodes reference the specific trigger that started the execution.

## Variable definitions

Variable definitions live in the **Variables** tab of the properties panel. Each definition stores the variable name, type, and direction so the value can be referenced consistently during a run.

![Properties panel with the Variables tab active, showing a variable named orderTotal with type set to Number.](https://dev-assets.cms.uipath.com/assets/images/maestro/flow-variables-tab-e70907e8.webp)

## Variable updates

Variables can be updated by node configuration or by Script node output.

**From any node — Update Variable section**

Every node has an **Update Variable** section in the properties panel. The section stores a writable variable target (output or bidirectional direction) and the JavaScript expression assigned to it. The expression is evaluated after the node completes.

![Properties panel showing the Update Variable section expanded on an HTTP Request node, with a variable selector dropdown and an expression field.](https://dev-assets.cms.uipath.com/assets/images/maestro/flow-update-variable-6e299e65.webp)

**From a Script node — return value**

A Script node's return value is accessible downstream as `$vars.<scriptName>.output`. The Script node also has the same Update Variable section as other nodes for direct variable writes:

```javascript
// The return value becomes $vars.script1.output
return {
  orderTotal: $vars.httpRequest1.output.body.price * $vars.httpRequest1.output.body.quantity
};
```

## Scoping rules

A node can access output from:

- **Upstream nodes in the same scope** — nodes at the same level that executed before it
- **Parent container nodes** — if the node is inside a subflow or loop, it can access the parent's scope

A node **cannot** access output from:

- **Nodes in a different branch** — if a Decision or Switch sent execution down a different path, those nodes' output is not available
- **Nodes that haven't executed** — output only exists after a node runs

### Subflow scoping

Subflows create their own variable scope. Nodes inside a subflow can access:

- Other nodes within the same subflow
- The parent process's scope

Variables updated inside a subflow are namespaced to avoid collisions with the parent process. For example, a variable `counter` inside a subflow named `subflow1` is referenced as `$vars.subflow1.counter` from outside the subflow.

The subflow's return value is accessible to the parent process as `$vars.<subflowName>.output`.

### Parallel branches

Parallel branches have independent execution contexts. Mutating a variable inside one branch does not make that change visible in another branch. A Merge node consolidates outputs from parallel paths when the paths need to rejoin.

## Patterns

### Building dynamic strings

Template literals in a Script node combine variables and static text:

```javascript
return `Hello ${firstName}, your order #${orderId} has shipped.`;
```

### Accumulating values in a loop

An accumulator pattern uses an array initialized before the Loop node and appended to inside the loop body:

```javascript
// Script node inside the Loop body
results.push(item.processedValue);
return results;
```

### Keeping secret values out of logs

Secret variable values are masked in the UI but may appear in exported trace data. Logging them is a data exposure risk.

## Practical example

A process that fetches a user from an API and routes based on their role:

**Step 1 — HTTP Request** (`httpRequest1`): GET `https://api.example.com/users/42`

**Step 2 — Script** (`script1`): Extract the user's role

```javascript
const user = $vars.httpRequest1.output.body;
return {
  name: user.name,
  role: user.role,
  isAdmin: user.role === "admin"
};
```

**Step 3 — Decision** (`decision1`): Branch on admin status

**Expression:** `$vars.script1.output.isAdmin === true`

- **True** → grant admin access
- **False** → grant standard access

## Related pages

- **[Expression syntax](expression-syntax.md)** — `$vars` grammar, operators, where you write expressions, common errors
- **[Script node](node-script.md)** — writing JavaScript, return values, `$vars` access
- **[Decision node](node-decision.md)** — branching on expressions
- **[The Canvas](canvas-overview.md)** — properties panel, Variables tab
