> ## Documentation Index
> Fetch the complete documentation index at: https://flowdrop.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Thinking in graphs

> Build intuition for nodes, edges, ports, and config by growing a familiar shell command into a workflow graph.

export const AsciiDiagram = ({children}) => {
  return <div className="ascii-diagram">{children}</div>;
};

This page builds the intuition behind every FlowDrop workflow. We start from a
single shell command you already know and grow it, one step at a time, into the
vocabulary FlowDrop uses: **process**, **graph**, **node**, **edge**, **port**,
and **configuration**.

You'll learn:

* Why a workflow is a graph of connected steps
* What a node and an edge are, and why they're separate things
* What ports add on top of edges
* How configuration differs from runtime input

Once these click, the formal terms in [What is a workflow?](/concepts/what-is-a-workflow)
will read as a recap rather than a wall of new words.

## 1. From command to process

Most things you run on a computer fit a simple shape: you give it something, it
does work, you see a result.

```cmd theme={null}
❯ capitalize "Hello World!"
❯ HELLO WORLD!
```

Three roles in this command:

| Item             | Role    | Function                     |
| ---------------- | ------- | ---------------------------- |
| `capitalize`     | Process | Runs a task on request       |
| `"Hello World!"` | Input   | What the process operates on |
| `HELLO WORLD!`   | Output  | What the user sees           |

<AsciiDiagram>
  ```
  ┌──────────┐      ┌─────────┐       ┌─────────┐
  │  Input   │─────▶│ Process │──────▶│ Output  │
  └──────────┘      └─────────┘       └─────────┘
  ```
</AsciiDiagram>

The same shape shows up everywhere:

1. A math function:

<AsciiDiagram>
  ```
    x ─▶ f(x) ─▶ y
  ```
</AsciiDiagram>

2. A computer:

<AsciiDiagram>
  ```
  ┌──────────┐      ┌─────────┐       ┌─────────┐
  │ Keyboard │─────▶│Processor│──────▶│ Monitor │
  └──────────┘      └─────────┘       └─────────┘
  ```
</AsciiDiagram>

A FlowDrop workflow is built from this same shape, repeated and connected.

## 2. A process without user input

Some processes don't need anything from the user — you invoke them and they
produce a result.

```cmd theme={null}
❯ date
❯ Tue Apr 28 13:27:37 CEST 2026
```

<AsciiDiagram>
  ```
  ┌──────────┐      ┌─────────┐       ┌─────────┐
  │ Get Date │─────▶│  Clock  │──────▶│ Display │
  └──────────┘      └─────────┘       └─────────┘
  ```
</AsciiDiagram>

You typed `date` with no arguments — from your perspective, no input was
required. But something still set the process in motion. The act of invoking
`date` is a **trigger**: a signal that says "run now". `Get Date` plays that role
here — the arrow into `Clock` doesn't carry a value, it just fires the process.
`Clock` reads the system time on its own and hands the result to `Display`.

Notice this: not every arrow in a graph carries data. Some arrows just trigger
the next step. We'll come back to this distinction in [step 5](#5-graphs-nodes-and-edges),
where the difference becomes **trigger edges** versus **data edges**.

Keep `Get Date` and `Clock` in mind — they'll keep appearing as we add more
inputs.

## 3. Multiple inputs

Now we combine the no-input process from step 2 with a user-supplied value:

```cmd theme={null}
❯ date +%Y
❯ 2026
```

`+%Y` is a **format string** the user provides. The process needs both the
current date *and* the format to produce its output:

<AsciiDiagram>
  ```
  ┌──────────┐                                   
  │  Format  │───┐  ┌─────────┐                  
  └──────────┘   └──▶         │       ┌─────────┐
                    │  Clock  │──────▶│ Display │
  ┌──────────┐   ┌──▶         │       └─────────┘
  │ Get Date │───┘  └─────────┘                  
  └──────────┘                                   
  ```
</AsciiDiagram>

Two arrows now feed into `Clock`, and they're not the same kind. `Get Date` is
still the trigger from step 2 — it tells `Clock` to run but carries no value.
`Format` is different: it carries the actual format string `+%Y` into the
process. One arrow triggers, the other delivers data, and a single process can
take any mix of the two.

## 4. Configuration vs. runtime input

What if some inputs are settings you decide once when building the workflow,
rather than values that arrive each time it runs?

```cmd theme={null}
# Set the system-wide default for timezone.
❯ set TZ="Asia/Tokyo" 
```

```cmd theme={null}
❯ date
❯ Tue Apr 28 20:34:42 JST 2026
```

```cmd theme={null}
# Override the system-wide default timezone at runtime.
❯ date -z "CET"
❯ Tue Apr 28 13:34:47 CEST 2026
```

Same `date` command, different output — because `TZ` was set as an environment
variable, not passed as an argument. It's part of how the process is configured
to run, not data that flows in for this particular invocation.

We draw this kind of value *inside* the process box to mark it as
**configuration**:

<AsciiDiagram>
  ```
  ┌──────────┐      ┌────────────────────────┐               
  │ TimeZone │──────▶         Clock          │               
  └──────────┘      │                        │               
                    │                        │               
                    │                        │    ┌─────────┐
                    │    ┌──────────────┐    │───▶│ Display │
                    │    │   TimeZone   │    │    └─────────┘
                    │    ├──────────────┤    │               
  ┌──────────┐      │    │    Format    │    │               
  │ Get Date │──────▶    └──────────────┘    │               
  └──────────┘      └────────────────────────┘               
  ```
</AsciiDiagram>

Notice `TimeZone` appears twice: once as an outside arrow (a runtime input that
could change each run) and once inside `Clock` (a configured default). The same
logical concept can be either, depending on how the workflow is wired. We'll
come back to this distinction in [step 7](#7-static-configuration-on-a-node).

## 5. Graphs: nodes and edges

We've been drawing the same shape — boxes connected by arrows — for four steps.
That shape has a name: a **graph**.

Here's the diagram from step 4 with the date-specific labels stripped away:

<AsciiDiagram>
  ```
  ┌──────────┐              ┌────────────────────────┐                       
  │  Node 1  │───Edge 1─────▶                        │                       
  └──────────┘              │                        │                       
                            │                        │                       
                            │                        │            ┌─────────┐
                            │         Node 3         │──Edge 3───▶│ Node 4  │
                            │                        │            └─────────┘
                            │                        │                       
  ┌──────────┐              │                        │                       
  │  Node 2  │───Edge 2─────▶                        │                       
  └──────────┘              └────────────────────────┘                       
  ```
</AsciiDiagram>

The graph has 4 **nodes** and 3 **edges**.

* A **node** is a step — a process box.
* An **edge** is a connection between two nodes — an arrow.

Nodes are *places*; edges are *one-way streets*. Nodes describe *what* happens;
edges describe *which step feeds which*.

In FlowDrop, edges carry a **category** that captures the trigger-versus-data
distinction from step 2: a `data` edge passes a value from one node's output to
another's input, while a `trigger` edge just fires the next node. (There are two
more categories, `tool` and `loopback`, for agent and loop workflows.) See
[Edge JSON](/guides/edge-json) for the full model.

A FlowDrop workflow is exactly this: a graph of nodes connected by edges.

## 6. Ports: typed connection points

Edges don't attach to nodes anywhere — they attach at specific spots called
**ports**.

* **Input ports** sit on the left of a node. They're where incoming edges land.
* **Output ports** sit on the right. They're where outgoing edges leave.

<AsciiDiagram>
  ```
                 ┌───────────────────────────────────┐             
                 ├──────────────┐                    │             
  ───Edge 1─────▶│ Input Port 1 │                    │             
                 ├──────────────┘                    │             
                 │                                   │             
                 │              Node 3               │             
                 │                                   │             
                 ├──────────────┐     ┌──────────────┤             
  ────Edge 2────▶│ Input Port 2 │     │Output Port 2 ├───Edge 3───▶
                 ├──────────────┘     └──────────────┤             
                 └───────────────────────────────────┘             
  ```
</AsciiDiagram>

Why name ports separately from edges? Because ports are **typed**: a port that
expects a number won't accept an edge carrying text. The type system catches
mistakes when you build the workflow rather than when it runs.

In the editor, ports are color-coded by data type — string, number, boolean,
date, file, and so on. See the [Port system](/guides/port-system) for how data
types and compatibility rules work.

## 7. Static configuration on a node

We hinted at this in step 4: not every value needs to flow in through an edge.
Some values are decided once when you build the workflow and stay put. Those are
stored as **configuration** directly on the node.

<AsciiDiagram>
  ```
                ┌────────────────────────┐            
  ───Edge 1─────▶         Node 3         │            
                │                        │            
                │                        │            
                │                        │            
                │    ┌──────────────┐    │──Edge 3───▶
                │    │   TimeZone   │    │            
                │    ├──────────────┤    │            
                │    │    Format    │    │            
  ───Edge 2─────▶    └──────────────┘    │            
                └────────────────────────┘            
  ```
</AsciiDiagram>

The inner boxes you saw all along — `TimeZone`, `Format` — are the node's
configuration. The distinction matters:

* **Ports** carry **dynamic** values. They're computed every time the workflow
  runs, by upstream nodes.
* **Configuration** holds **static** values. You set them once in the editor;
  they don't change between runs.

When you design a workflow, deciding what should be a port versus what should be
configuration shapes how reusable the node is. A `TimeZone` configured on the
node fixes that workflow to one zone. The same `TimeZone` exposed as a port lets
each run pick its own.

In FlowDrop, a node's configuration is defined by a [JSON Schema](/guides/config-schema),
which the editor renders as a form when you click the node.

## Recap

| Term              | Meaning                                                   |
| ----------------- | --------------------------------------------------------- |
| **Process**       | A step that turns inputs into outputs                     |
| **Graph**         | A set of processes connected by arrows                    |
| **Node**          | A single step in the graph                                |
| **Edge**          | A one-way connection between two nodes                    |
| **Port**          | A typed connection point on a node where an edge attaches |
| **Configuration** | Static values set on a node when the workflow is built    |

## Next steps

* [What is a workflow?](/concepts/what-is-a-workflow) — the four primitives,
  stated formally, plus what FlowDrop does and doesn't do.
* [Architecture overview](/concepts/architecture-overview) — how the pieces fit
  together.
* Build something: [Embedding the editor](/tutorial/01-embedding-the-editor).
