n8n Code Node Generator

JavaScript code snippets for common n8n Code node tasks

Flatten Nested Array

Flatten a deeply nested array into a single level

Data Transformation
// Flatten nested arrays
const items = $input.all();
const flattenedItems = [];

function flattenArray(arr) {
  for (const item of arr) {
    if (Array.isArray(item.json.data)) {
      flattenArray(item.json.data.map(d => ({ json: d })));
    } else {
      flattenedItems.push(item);
    }
  }
}

flattenArray(items);
return flattenedItems;

Group Items by Key

Group array items by a specific property

Data Transformation
// Group items by a key
const items = $input.all();
const groupKey = 'category'; // Change this to your key

const grouped = {};
for (const item of items) {
  const key = item.json[groupKey] || 'unknown';
  if (!grouped[key]) {
    grouped[key] = [];
  }
  grouped[key].push(item.json);
}

return Object.entries(grouped).map(([key, values]) => ({
  json: { [groupKey]: key, items: values, count: values.length }
}));

Remove Duplicates

Remove duplicate items based on a key

Data Transformation
// Remove duplicates by key
const items = $input.all();
const uniqueKey = 'id'; // Change this to your unique key

const seen = new Set();
const uniqueItems = [];

for (const item of items) {
  const key = item.json[uniqueKey];
  if (!seen.has(key)) {
    seen.add(key);
    uniqueItems.push(item);
  }
}

return uniqueItems;

Split into Batches

Split items into smaller batches for processing

Data Transformation
// Split items into batches
const items = $input.all();
const batchSize = 10; // Change batch size as needed

const batches = [];
for (let i = 0; i < items.length; i += batchSize) {
  batches.push({
    json: {
      batchNumber: Math.floor(i / batchSize) + 1,
      items: items.slice(i, i + batchSize).map(item => item.json)
    }
  });
}

return batches;

Pivot Data

Transform rows into columns (pivot table)

Data Transformation
// Pivot data - transform rows to columns
const items = $input.all();
const rowKey = 'date';     // Row identifier
const pivotKey = 'metric'; // Column to pivot
const valueKey = 'value';  // Value to use

const pivoted = {};
for (const item of items) {
  const row = item.json[rowKey];
  const col = item.json[pivotKey];
  const val = item.json[valueKey];

  if (!pivoted[row]) {
    pivoted[row] = { [rowKey]: row };
  }
  pivoted[row][col] = val;
}

return Object.values(pivoted).map(row => ({ json: row }));

Format Date

Format dates in various formats

Date & Time
// Format dates
const items = $input.all();
const dateField = 'created_at'; // Your date field

return items.map(item => {
  const date = new Date(item.json[dateField]);

  return {
    json: {
      ...item.json,
      formatted: {
        iso: date.toISOString(),
        date: date.toLocaleDateString('en-US'),
        time: date.toLocaleTimeString('en-US'),
        unix: Math.floor(date.getTime() / 1000),
        relative: getRelativeTime(date)
      }
    }
  };
});

function getRelativeTime(date) {
  const now = new Date();
  const diff = now - date;
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (days > 0) return days + ' days ago';
  if (hours > 0) return hours + ' hours ago';
  if (minutes > 0) return minutes + ' minutes ago';
  return 'just now';
}

Generate Date Range

Generate a range of dates between start and end

Date & Time
// Generate date range
const startDate = new Date('2024-01-01');
const endDate = new Date('2024-01-31');

const dates = [];
const current = new Date(startDate);

while (current <= endDate) {
  dates.push({
    json: {
      date: current.toISOString().split('T')[0],
      dayOfWeek: current.toLocaleDateString('en-US', { weekday: 'long' }),
      isWeekend: [0, 6].includes(current.getDay())
    }
  });
  current.setDate(current.getDate() + 1);
}

return dates;

Add/Subtract Days

Add or subtract days from dates

Date & Time
// Add or subtract days from date
const items = $input.all();
const dateField = 'date';
const daysToAdd = 7; // Negative to subtract

return items.map(item => {
  const date = new Date(item.json[dateField]);
  date.setDate(date.getDate() + daysToAdd);

  return {
    json: {
      ...item.json,
      newDate: date.toISOString().split('T')[0]
    }
  };
});

Slugify Text

Convert text to URL-friendly slug

String Operations
// Slugify text
const items = $input.all();
const textField = 'title';

function slugify(text) {
  return text
    .toString()
    .toLowerCase()
    .trim()
    .replace(/\s+/g, '-')        // Replace spaces with -
    .replace(/[^\w\-]+/g, '')   // Remove non-word chars
    .replace(/\-\-+/g, '-')     // Replace multiple - with single -
    .replace(/^-+/, '')           // Trim - from start
    .replace(/-+$/, '');          // Trim - from end
}

return items.map(item => ({
  json: {
    ...item.json,
    slug: slugify(item.json[textField])
  }
}));

Extract Emails

Extract all email addresses from text

String Operations
// Extract emails from text
const items = $input.all();
const textField = 'content';

const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;

return items.map(item => {
  const text = item.json[textField] || '';
  const emails = text.match(emailRegex) || [];

  return {
    json: {
      ...item.json,
      extractedEmails: [...new Set(emails)],
      emailCount: emails.length
    }
  };
});

Truncate Text

Truncate text with ellipsis

String Operations
// Truncate text with ellipsis
const items = $input.all();
const textField = 'description';
const maxLength = 100;

function truncate(text, max) {
  if (!text || text.length <= max) return text;
  return text.slice(0, max).trim() + '...';
}

return items.map(item => ({
  json: {
    ...item.json,
    truncated: truncate(item.json[textField], maxLength)
  }
}));

Calculate Statistics

Calculate sum, average, min, max from numbers

Calculations
// Calculate statistics
const items = $input.all();
const numberField = 'amount';

const values = items
  .map(item => parseFloat(item.json[numberField]))
  .filter(n => !isNaN(n));

const stats = {
  count: values.length,
  sum: values.reduce((a, b) => a + b, 0),
  min: Math.min(...values),
  max: Math.max(...values),
  average: values.reduce((a, b) => a + b, 0) / values.length,
  median: getMedian(values)
};

function getMedian(arr) {
  const sorted = [...arr].sort((a, b) => a - b);
  const mid = Math.floor(sorted.length / 2);
  return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
}

return [{ json: stats }];

Calculate % Change

Calculate percentage change between values

Calculations
// Calculate percentage change
const items = $input.all();
const valueField = 'value';

return items.map((item, index) => {
  const currentValue = parseFloat(item.json[valueField]);
  let percentChange = null;

  if (index > 0) {
    const previousValue = parseFloat(items[index - 1].json[valueField]);
    if (previousValue !== 0) {
      percentChange = ((currentValue - previousValue) / previousValue * 100).toFixed(2);
    }
  }

  return {
    json: {
      ...item.json,
      percentChange: percentChange ? parseFloat(percentChange) : null,
      trend: percentChange > 0 ? 'up' : percentChange < 0 ? 'down' : 'flat'
    }
  };
});

Retry with Backoff

Implement retry logic with exponential backoff

API Helpers
// Retry with exponential backoff
const maxRetries = 3;
const baseDelay = 1000; // 1 second

async function fetchWithRetry(url, options = {}) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return await response.json();
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      const delay = baseDelay * Math.pow(2, attempt);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Usage:
// const data = await fetchWithRetry('https://api.example.com/data');
return [{ json: { message: 'Retry helper ready' } }];

Rate Limiter

Process items with rate limiting

API Helpers
// Rate limiter - process items with delay
const items = $input.all();
const delayMs = 200; // 200ms between items (5 per second)

const results = [];

for (let i = 0; i < items.length; i++) {
  // Process item
  results.push({
    json: {
      ...items[i].json,
      processedAt: new Date().toISOString(),
      index: i + 1
    }
  });

  // Add delay except for last item
  if (i < items.length - 1) {
    await new Promise(resolve => setTimeout(resolve, delayMs));
  }
}

return results;

Safe Data Access

Safely access nested properties without errors

Error Handling
// Safely access nested properties
const items = $input.all();

function safeGet(obj, path, defaultValue = null) {
  return path.split('.').reduce((acc, part) => {
    return acc && acc[part] !== undefined ? acc[part] : defaultValue;
  }, obj);
}

return items.map(item => ({
  json: {
    // Safely access nested properties
    id: safeGet(item.json, 'user.profile.id', 'unknown'),
    email: safeGet(item.json, 'user.contact.email', 'no-email'),
    name: safeGet(item.json, 'user.profile.name', 'Anonymous'),
    // Original data
    _raw: item.json
  }
}));

Validate Data

Validate items and separate valid/invalid

Error Handling
// Validate data and separate valid/invalid items
const items = $input.all();

function validate(item) {
  const errors = [];

  if (!item.email) errors.push('Email is required');
  else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(item.email)) {
    errors.push('Invalid email format');
  }

  if (!item.name) errors.push('Name is required');
  if (item.age && (item.age < 0 || item.age > 150)) {
    errors.push('Age must be between 0 and 150');
  }

  return errors;
}

const valid = [];
const invalid = [];

for (const item of items) {
  const errors = validate(item.json);
  if (errors.length === 0) {
    valid.push(item);
  } else {
    invalid.push({ json: { ...item.json, validationErrors: errors } });
  }
}

// Return both arrays
return [
  { json: { type: 'valid', count: valid.length, items: valid.map(i => i.json) } },
  { json: { type: 'invalid', count: invalid.length, items: invalid.map(i => i.json) } }
];

How to Use

1. Find Your Snippet

Browse categories or search for the functionality you need. Each snippet is self-contained and ready to use.

2. Copy and Paste

Click the copy button and paste directly into your n8n Code node. The code works with n8n's JavaScript execution environment.

3. Customize

Update field names and values to match your workflow data. Comments in the code indicate what to change.

Why Use Code Nodes in n8n Workflows?

The n8n Code node lets you write JavaScript to transform data, implement custom logic, and handle edge cases that built-in nodes can't cover. This free code snippet library gives you ready-to-use patterns.

The Problem: Complex Data Transformations

While n8n has powerful built-in nodes, some operations require custom code:

  • Complex data reshaping and pivoting
  • Custom validation and error handling
  • Advanced date/time calculations
  • Text processing and extraction
  • Statistical calculations and aggregations

The Solution: Pre-Built Code Snippets

Stop writing the same code over and over. These snippets are tested, optimized, and ready to use in your n8n Code nodes.

Categories Available

  • Data Transformation - Flatten, group, deduplicate, batch, pivot
  • Date & Time - Format, generate ranges, add/subtract days
  • String Operations - Slugify, extract emails, truncate
  • Calculations - Statistics, percentage change
  • API Helpers - Retry logic, rate limiting
  • Error Handling - Safe access, validation

Why Use These Snippets?

  • Battle-Tested - Used in production workflows
  • Well-Commented - Easy to understand and customize
  • n8n Compatible - Works with $input, $json patterns
  • Copy & Paste - Ready to use immediately
  • Free Forever - No sign-up required

Need Help Building n8n Workflows?

FlowEngine makes it easy to create powerful n8n automation workflows with AI assistance.

Try FlowEngine Free