How to Use JavaScript in n8n: A Step-by-Step Guide

In today’s digital age, automating repetitive tasks is crucial to improving productivity and efficiency. Workflow automation tools have become essential in this process, enabling users to connect apps and services seamlessly. One such tool that’s gaining widespread adoption is n8n—an open-source, powerful, and flexible automation platform.

While n8n is designed to make automation accessible through its intuitive visual interface, there are times when you want to push beyond pre-built nodes. You want custom logic, data transformation, or filtering that isn’t possible with out-of-the-box features. That’s where JavaScript comes into play. By writing JavaScript inside n8n, you unlock unlimited customization potential.

This guide will walk you through everything you need to know to start using JavaScript in n8n. From the basics of the platform, to how the Function node works, to practical JavaScript examples and best practices, by the end, you’ll be confidently using code to enhance your workflows and automate like a pro.

What is n8n and Why Should You Use JavaScript in It?

What Exactly is n8n?

n8n (pronounced “n-eight-n”) stands for “node to node.” It is an open-source workflow automation tool that lets you connect over 200 different apps and services, such as Google Sheets, Slack, Twitter, GitHub, and more. Its visual interface allows you to drag and drop nodes to design workflows that automate data movement, processing, and notifications.

Unlike many automation platforms, n8n is open source, meaning you can self-host it for free or use their cloud version. This openness offers greater control over your data, extensibility, and flexibility.

Why Use JavaScript with n8n?

While n8n has many pre-built nodes covering common automation tasks, sometimes your use case requires more sophisticated logic or data manipulation. For example, you might want to:

  • Combine data fields into a custom format
  • Apply conditional filters to data before processing
  • Calculate values based on complex business rules
  • Generate dynamic content for emails or messages
  • Enrich data with timestamps or unique identifiers

In such cases, JavaScript is your best friend. It’s the scripting language n8n uses inside special nodes (like the Function node) to give you full control over your workflow’s data.

Getting Started with n8n: Installation and First Workflow

How to Get n8n Running

If you’re new to n8n, here are the easiest ways to get started:

  • Cloud version: Sign up for an account at n8n.cloud and start building workflows instantly.
  • Local installation: If you prefer to run it on your own machine, install Node.js (version 16+ recommended), then install n8n via npm:

Bash
npm install n8n -g
n8n start
  • Docker: Use Docker if you’re familiar with containerization. Run:

Bash
docker run -it --rm \
  -p 5678:5678 \
  -v ~/.n8n:/home/node/.n8n \
  n8nio/n8n
  

Choose the method that fits your setup and comfort level.

Create Your First Simple Workflow

Before diving into JavaScript, let’s create a basic workflow to see how n8n functions.

  1. Open your n8n editor UI.
  2. Add a Webhook Trigger node. This will start your workflow when an HTTP request is received.
  3. Add a Set node, which lets you define some simple data (e.g., { "message": "Hello World" }).
  4. Connect the Webhook node to the Set node.
  5. Save and activate your workflow.
  6. Trigger it by sending an HTTP request to the webhook URL.

You now have a working workflow that passes data between nodes. This is important because when you add JavaScript, you’ll be manipulating this data flow.

The Function Node: Your JavaScript Editor Inside n8n

To write JavaScript in n8n, you use the Function node or FunctionItem node.

Function Node vs. FunctionItem Node

  • Function node: Processes all input data at once. Input is an array of items (objects). Your JavaScript processes this entire array and returns a new array.
  • FunctionItem node: Processes one item at a time. Your code runs once for each item in the input.

The Function node is more powerful for data transformation and aggregation, so we’ll focus on it.

Anatomy of a Function Node Script

n8n expects your JavaScript to return an array of objects. Each object should have a json key with the data you want to pass along.

Here’s the simplest Function node script:

JavaScript
return [
  {
    json: {
      message: "Hello from JavaScript"
    }
  }
];

This returns an array with a single item, containing a JSON object with a message.

Practical JavaScript Examples in n8n

Let’s walk through some examples that you can try inside a Function node to better understand how to manipulate data.

Example 1: Basic Math Calculation

Suppose you want to calculate the square of a number and pass it forward:

JavaScript
const number = 7;
return [{ json: { square: number * number } }];

What this does:

  • Creates a constant number with value 7
  • Calculates the square (7 × 7 = 49)
  • Returns a JSON object with the square

Example 2: Transform Data Fields

Imagine your incoming data has firstName and lastName fields, and you want to combine them into fullName.

JavaScript
const input = items[0].json;
const fullName = `${input.firstName} ${input.lastName}`;

return [{ json: { fullName } }];

If the input is:

JSON
{
  "firstName": "Alice",
  "lastName": "Johnson"
}

The output becomes:

JSON
{
  "fullName": "Alice Johnson"
}

Example 3: Conditional Data Filtering

Suppose you want to pass only users aged 18 or above.

JavaScript
const input = items[0].json;

if (input.age >= 18) {
  return [items[0]];
} else {
  return [];
}

If the user is 16, the workflow stops here. If 20, the data moves forward.

Example 4: Process Multiple Items

If your input has multiple items, you can loop through and update each one.

JavaScript
const newItems = items.map(item => {
  item.json.fullName = `${item.json.firstName} ${item.json.lastName}`;
  return item;
});

return newItems;

This transforms each item in the array, adding a fullName field.

Example 5: Adding Timestamps

Add a current timestamp to each data item:

JavaScript
const now = new Date().toISOString();

const newItems = items.map(item => {
  item.json.timestamp = now;
  return item;
});

return newItems;

This is helpful for logging or auditing data.

Understanding the Data Structure: The Key to Success

Understanding how n8n handles data inside workflows is essential for effective JavaScript coding.

  • Items: Your data is an array called items.
  • Item: Each element in items is an object with a json property.
  • Accessing data: You access fields like this: items[0].json.fieldName.

Example input:

JSON
[
  {
    "json": {
      "firstName": "John",
      "lastName": "Doe",
      "age": 28
    }
  },
  {
    "json": {
      "firstName": "Jane",
      "lastName": "Smith",
      "age": 22
    }
  }
]

Inside JavaScript, items[0].json.firstName equals "John".

Can You Use External JavaScript Libraries?

A common question is whether you can import popular JavaScript libraries like Lodash or Moment.js.

Currently, n8n does not allow importing external libraries inside the Function node. You’re limited to vanilla JavaScript only.

Why This Limitation?

  • Security: Allowing arbitrary code and libraries could pose risks.
  • Lightweight: Keeping the environment small improves performance and reliability.
  • Complexity: Managing library dependencies would complicate the environment.

Workarounds to Use Libraries or APIs

  • Use the HTTP Request node: Instead of running a library locally, call an external API that provides the functionality. For example, use a date API instead of Moment.js.
  • Copy-paste small functions: If a library function is small and simple, copy its code into your Function node (respecting licenses).
  • Use n8n’s built-in nodes: n8n has many nodes and community nodes to cover common tasks without code.

Tips and Best Practices for Writing JavaScript in n8n

Writing JavaScript inside workflows is powerful but comes with responsibility. Follow these tips to write clean, maintainable code.

1. Always Validate Your Input

Check if items exists and contains data before processing.

JavaScript
if (!items || items.length === 0) {
  return [];
}

This prevents errors when data is missing.

2. Use console.log for Debugging

You can print variables and messages to the log.

JavaScript
console.log('Received items:', items);

This helps track what your code sees at runtime.

3. Keep Your Code Modular

Break complex logic into smaller functions inside the node.

JavaScript
function formatName(first, last) {
  return `${first} ${last}`;
}

const newItems = items.map(item => {
  item.json.fullName = formatName(item.json.firstName, item.json.lastName);
  return item;
});

return newItems;

Modular code is easier to debug and maintain.

4. Handle Errors Gracefully

Use try-catch blocks to catch and log errors without breaking your workflow.

JavaScript
try {
  // your code
} catch (error) {
  console.error('Error in function node:', error);
  return [];
}

5. Comment Your Code

Add comments to explain your logic for future you or other collaborators.

Real-World Use Cases of JavaScript in n8n Workflows

To inspire you, here are some practical ways people use JavaScript in n8n.

Dynamic Email Personalization

Send personalized greetings based on time of day:

JavaScript
const hour = new Date().getHours();
let greeting;

if (hour < 12) {
  greeting = "Good morning";
} else if (hour < 18) {
  greeting = "Good afternoon";
} else {
  greeting = "Good evening";
}

return [{ json: { greeting } }];

Filter Data Before Saving

Only save orders over a threshold amount:

JavaScript
const filteredItems = items.filter(item => item.json.orderTotal > 100);
return filteredItems;

Enrich Data with Metadata

Add source or tracking info before sending to APIs:

JavaScript
const newItems = items.map(item => {
  item.json.source = "n8n Workflow";
  item.json.processedAt = new Date().toISOString();
  return item;
});

return newItems;

Complex Calculations and Logic

Calculate discounts, taxes, or score leads using custom formulas.

Advanced: Async JavaScript in n8n

Currently, n8n’s Function node does not support asynchronous JavaScript with await. All code must be synchronous.

For async operations, use other nodes like HTTP Request or Execute Command nodes.

Summary and Next Steps

Using JavaScript inside n8n workflows elevates your automation from simple to sophisticated. By mastering the Function node, you can:

  • Transform and enrich data on the fly
  • Apply custom logic and filters
  • Generate dynamic content
  • Integrate complex calculations

Here are your next steps:

  • Experiment with the Function node in a test workflow.
  • Try combining JavaScript with other n8n nodes.
  • Explore the official n8n docs for deeper features.
  • Join the n8n community forums to ask questions and share ideas.