Node.js 22 Upgrade Guide

Homey Apps now run in a Node.js v22 environment (Homey v12.9.0+), upgraded from Node.js v16 and v18 (Learn more). While Node.js updates are generally backwards compatible, some issues may arise. Below are the currently known issues and solutions listed.

Known issues

HTTP(S) calls failing due to "socket hang up"/"ECONNRESET" when using node-fetch

Node.js 19 introduced changes to the management of keep-alive sockets. When using node-fetch, this might cause an ECONNRESET error under certain circumstances, particularly with services that aggressively close idle connections:

FetchError: request to <> failed, reason: socket hang up
    at ClientRequest.<anonymous> (file:///app/node_modules/node-fetch/src/index.js:109:11)
    at ClientRequest.emit (node:events:519:28)
    at emitErrorEvent (node:_http_client:105:11)
    at Socket.socketOnEnd (node:_http_client:542:5)
    at Socket.emit (node:events:531:35)
    at endReadableNT (node:internal/streams/readable:1698:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:90:21) {
  type: 'system',
  errno: 'ECONNRESET',
  code: 'ECONNRESET',
  erroredSysCall: undefined
}

For more information see this GitHub issue.

Solutions

Provide a custom http.Agent or https.Agent instance to your node-fetch requests. This ensures proper keep-alive socket management:

const fetch = require("node-fetch");
const http = require("http");
const https = require("https");

// Create an agent with keep-alive enabled
const httpAgent = new http.Agent({ keepAlive: true });
const httpsAgent = new https.Agent({ keepAlive: true });

// Use the appropriate agent for your request
fetch("https://example.com/api", {
  agent: (_parsedURL) =>
    _parsedURL.protocol === "http:" ? httpAgent : httpsAgent,
});

Node.js 18+ includes a native fetch() implementation that handles socket management automatically:

// No imports needed, fetch is globally available
const response = await fetch("https://example.com/api");
const data = await response.json();

The built-in fetch is the preferred approach for new code as it's maintained as part of Node.js and doesn't require external dependencies.

Last updated

Was this helpful?