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

# Custom code

The **Custom Code** node runs Python inside a flow, for the steps no built-in node covers. It sits in the **Workflow Basics** category.

<Note>
  The AI builder can handle this node for you. Describe what the step should do in **Chat** mode, and it writes the code, sets up its inputs and outputs, and tests it before adding it to your flow. See [Build with AI](/flows/build-with-ai).
</Note>

## How it works

The code lives in the **Code** field, written as a `process` function that receives the node's inputs and returns its outputs.

The ports on the node come from what is declared. Each row under **Declared Inputs** becomes a field you can wire an earlier node into, and each row under **Declared Outputs** becomes a value later nodes can use. Every row has a name and a type.

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/qx-labs/ZJkiVX6zo-84vXkk/images/flows/nodes/custom-code/custom-code-node-light.png?fit=max&auto=format&n=ZJkiVX6zo-84vXkk&q=85&s=0921bbc82b1b3f5e5bfd630a5b4f0745" alt="A Custom Code node showing the code editor with declared inputs and outputs" width="1919" height="951" data-path="images/flows/nodes/custom-code/custom-code-node-light.png" />

  <img className="hidden dark:block" src="https://mintcdn.com/qx-labs/ZJkiVX6zo-84vXkk/images/flows/nodes/custom-code/custom-code-node-dark.png?fit=max&auto=format&n=ZJkiVX6zo-84vXkk&q=85&s=35606c858904146b0ab7631bf91605db" alt="A Custom Code node showing the code editor with declared inputs and outputs" width="1919" height="951" data-path="images/flows/nodes/custom-code/custom-code-node-dark.png" />
</Frame>

Two more settings matter when the code does something heavier. **Pip Packages** installs any Python libraries it needs, and **Timeout (seconds)** caps how long it may run before the flow gives up on it.

If you do edit the code by hand, it must return a value for every declared output, and nothing is kept between runs, so treat each run as a fresh start.
