Back to list
aixier

n8n-best-practices

by aixier

Monorepo for n8n workflow automation with Claude Code integration - 7 skills + 14+ code modules + Python agent

0🍴 1📅 Nov 3, 2025

SKILL.md


name: n8n-best-practices description: Use when encountering n8n workflow issues, Code node errors, HTTP requests failing, data flow problems, environment variables not working, JSON parsing errors, or need n8n development patterns and debugging strategies

n8n Best Practices

When to use this skill: Any time you're working with n8n workflows and encounter errors, unexpected behavior, or need guidance on implementation patterns.

Critical Knowledge Base

🚨 ES5 Syntax Only in Code Nodes

n8n Code nodes only support ES5 JavaScript. Modern ES6+ syntax will fail.

❌ DO NOT USE:

// Arrow functions
const process = (item) => item.value;

// Template literals
const url = `https://api.example.com/${id}`;

// const/let
const value = 123;

// Destructuring
const { name, age } = person;

// Spread operator in function calls
Math.max(...numbers);

✅ USE INSTEAD:

// Regular functions
var process = function(item) {
  return item.value;
};

// String concatenation
var url = 'https://api.example.com/' + id;

// var only
var value = 123;

// Manual assignment
var name = person.name;
var age = person.age;

// apply() for spread
Math.max.apply(null, numbers);

// Object spread alternative
var merged = Object.assign({}, obj1, obj2);

🌐 HTTP Requests in Code Nodes

CRITICAL: $http and axios are NOT available in Code nodes.

❌ WRONG:

const response = await $http.request({url: 'https://api.example.com'});
const axios = require('axios');

✅ CORRECT - Use Native HTTPS:

var https = require('https');

function makeRequest(url, options) {
  return new Promise(function(resolve, reject) {
    var req = https.request(options, function(res) {
      var data = '';
      res.on('data', function(chunk) { data += chunk; });
      res.on('end', function() {
        resolve({statusCode: res.statusCode, body: data});
      });
    });
    req.on('error', reject);
    req.end();
  });
}

// Usage
var result = await makeRequest('example.com', {
  hostname: 'example.com',
  path: '/api/endpoint',
  method: 'POST',
  headers: {'Content-Type': 'application/json'}
});

🔐 Environment Variables Configuration

CRITICAL: Variables must be explicitly exported, not just sourced.

❌ WRONG:

source .env.local
pnpm start
# Variables will be undefined in Code nodes!

✅ CORRECT:

#!/bin/bash
export NOTION_API_KEY=$(grep NOTION_API_KEY .env.local | cut -d '=' -f2)
export QWEN_API_KEY=$(grep QWEN_API_KEY .env.local | cut -d '=' -f2)
export NODE_FUNCTION_ALLOW_BUILTIN=*
export N8N_BLOCK_ENV_ACCESS_IN_NODE=false
pnpm start

Access in Code nodes:

var apiKey = process.env.NOTION_API_KEY;  // Not $env

📦 gzip Compression Issues

Problem: HTTP requests with gzip compression return garbled data.

❌ WRONG:

headers: {
  'Accept-Encoding': 'gzip, deflate'
}
// Returns: �������

✅ CORRECT:

headers: {
  'Content-Type': 'application/json'
  // DO NOT include Accept-Encoding header
}

🔄 Data Flow Patterns

Always preserve upstream data:

✅ CORRECT:

return {
  json: Object.assign({}, $input.item.json, {
    newField: newValue
  })
};

❌ WRONG:

return {
  json: {
    newField: newValue  // Loses all previous data!
  }
};

📋 JSON Parsing Best Practices

❌ WRONG:

var data = JSON.parse(response);
// May return undefined without error

✅ CORRECT:

function safeJSONParse(text) {
  try {
    var parsed = JSON.parse(text);
    if (parsed && typeof parsed === 'object') {
      return parsed;
    }
    throw new Error('Parsed value is not an object');
  } catch (e) {
    throw new Error('JSON parsing failed: ' + e.message);
  }
}

var data = safeJSONParse(response);

🔧 Code Node Sandbox Configuration

macOS launchd service:

<key>EnvironmentVariables</key>
<dict>
  <key>NODE_FUNCTION_ALLOW_BUILTIN</key>
  <string>*</string>
</dict>

Shell script:

export NODE_FUNCTION_ALLOW_BUILTIN=*
n8n start

🐛 Common Pitfalls

1. Aggregate Node Array Wrapping

// Aggregate converts: {field: value} → {field: [value]}
var data = $input.first().json;
var actualValue = data.field[0];  // Must access array

2. Split Into Batches Data Loss

// ❌ WRONG: Loses data
return items.map(function(item) {
  return {json: {processed: true}};
});

// ✅ CORRECT: Preserves data
return items.map(function(item) {
  return {
    json: Object.assign({}, item.json, {processed: true})
  };
});

3. require() Module Access

// Only available if NODE_FUNCTION_ALLOW_BUILTIN=*
var https = require('https');  // ✅ Works
var axios = require('axios');  // ❌ Not available

Quick Reference

When Code node fails:

  1. Check ES5 syntax (no arrow functions, template literals)
  2. Verify environment variables are exported
  3. Use require('https') not $http
  4. Remove Accept-Encoding header for gzip issues

When data is lost:

  1. Always spread previous data: Object.assign({}, $input.item.json, newData)
  2. Check Aggregate node array wrapping
  3. Verify Split Into Batches preserves data

When environment variables are undefined:

  1. Use export, not source
  2. Access with process.env.VAR, not $env.VAR
  3. Set N8N_BLOCK_ENV_ACCESS_IN_NODE=false

Full Documentation

For complete details, examples, and advanced patterns, see: /mnt/d/work/n8n_agent/n8n-skills/n8n-best-practices/README.md

Score

Total Score

55/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

0/5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon