Npm packages installed in Docker container not found by n8n

correctly installed npm package inside Docker container can’t be found by n8n instance

I have a container running with Docker Compose with the following setup

Dockerfile:

FROM docker.n8n.io/n8nio/n8n
USER root
RUN npm install -g fuse.js
USER node

compose.yaml

services:
  n8n:
    container_name: n8n
    build: .
    restart: always
    ports:
      - "5678:5678"
    environment:
      - NODE_FUNCTION_ALLOW_EXTERNAL=*
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:

When I try to run the code below inside a Code Node

const fuse = require('fuse.js')

I get this error

Cannot find module 'fuse.js' Require stack: - /usr/local/lib/node_modules/n8n/node_modules/.pnpm/@n8n+task-runner@file+packages+@n8n+task-runner_@[email protected]_@opentelemetry_eb51b38615a039445701c88b088f88d0/node_modules/@n8n/task-runner/dist/js-task-runner/require-resolver.js - /usr/local/lib/node_modules/n8n/node_modules/.pnpm/@n8n+task-runner@file+packages+@n8n+task-runner_@[email protected]_@opentelemetry_eb51b38615a039445701c88b088f88d0/node_modules/@n8n/task-runner/dist/js-task-runner/js-task-runner.js - /usr/local/lib/node_modules/n8n/node_modules/.pnpm/@n8n+task-runner@file+packages+@n8n+task-runner_@[email protected]_@opentelemetry_eb51b38615a039445701c88b088f88d0/node_modules/@n8n/task-runner/dist/start.js

I even tried using the Docker container shell to check which packages were installed in the container and it does show that fuse.js is installed globally.

~ $ npm list -g
/opt/nodejs/node-v22.21.1/lib
+-- [email protected]
+-- [email protected]
+-- [email protected]
`-- [email protected]

Information on your n8n setup

  • n8n version: 2.4.5
  • Database (default: SQLite): none
  • n8n EXECUTIONS_PROCESS setting (default: own, main): none
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker Compose
  • Operating system: Debian 13 - Trixie

I managed to make it work by putting the whole path inside the require:

const Fuse = require("/opt/nodejs/node-v22.21.1/lib/node_modules/fuse.js/dist/fuse.cjs")

I’m posting this anyway because to me it seems like an issue that it wouldn’t find a globally installed package. It feels like n8n is looking in the wrong directories to find the module. Maybe other users will benefit from my solution as well.

Thanks for sharing your solution @simone-putzu

Instead of using the full path which is fragile and version dependent, install the package locally in n8n’s node_modules:

Updated Dockerfile:

FROM docker.n8n.io/n8nio/n8n
USER root

# Install to n8n's local node_modules instead of globally
RUN cd /usr/local/lib/node_modules/n8n && npm install fuse.js

USER node

Then in your Code node, use the standard require:

const Fuse = require('fuse.js');

Your Environment Variable is Correct:

environment:
  - NODE_FUNCTION_ALLOW_EXTERNAL=*

This allows external modules - you just need them in the right location.

Alternative: Use a Volume Mount

If you prefer more control:

volumes:
  - n8n_data:/home/node/.n8n
  - ./local-files:/files
  - ./custom_modules:/usr/local/lib/node_modules/n8n/node_modules/custom

Then install packages in ./custom_modules/ on your host.

Your workaround with the full path works, but the local installation approach is cleaner. Thanks for documenting this, it’ll definitely help others facing the same issue!

I just tried what you said but it gives me an error with the npm install command. I ran it directly from the Docker shell to show you the full output:

/usr/local/lib/node_modules/n8n $ npm install fuse.js
npm error code EUNSUPPORTEDPROTOCOL
npm error Unsupported URL Type "catalog:": catalog:
npm error A complete log of this run can be found in: /home/node/.npm/_logs/2026-02-03T11_44_04_468Z-debug-0.log

/usr/local/lib/node_modules/n8n $ cat /home/node/.npm/_logs/2026-02-03T11_44_04_468Z-debug-0.log
0 verbose cli /opt/nodejs/node-v22.21.1/bin/node /usr/local/bin/npm
1 info using [email protected]
2 info using [email protected]
3 silly config load:file:/opt/nodejs/node-v22.21.1/lib/node_modules/npm/npmrc
4 silly config load:file:/usr/local/lib/node_modules/n8n/.npmrc
5 silly config load:file:/home/node/.npmrc
6 silly config load:file:/opt/nodejs/node-v22.21.1/etc/npmrc
7 verbose title npm install fuse.js
8 verbose argv "install" "fuse.js"
9 verbose logfile logs-max:10 dir:/home/node/.npm/_logs/2026-02-03T11_44_04_468Z-
10 verbose logfile /home/node/.npm/_logs/2026-02-03T11_44_04_468Z-debug-0.log
11 silly logfile done cleaning log files
12 silly packumentCache heap:2197815296 maxSize:549453824 maxEntrySize:274726912
13 silly idealTree buildDeps
14 verbose stack Error: Unsupported URL Type "catalog:": catalog:
14 verbose stack     at unsupportedURLType (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/npm-package-arg/lib/npa.js:367:15)
14 verbose stack     at fromURL (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/npm-package-arg/lib/npa.js:426:13)
14 verbose stack     at Function.resolve (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/npm-package-arg/lib/npa.js:108:12)
14 verbose stack     at #nodeFromEdge (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:1053:22)
14 verbose stack     at #buildDepStep (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:918:35)
14 verbose stack     at #buildDeps (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:770:30)
14 verbose stack     at Arborist.buildIdealTree (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js:170:28)
14 verbose stack     at async Promise.all (index 1)
14 verbose stack     at async Arborist.reify (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/node_modules/@npmcli/arborist/lib/arborist/reify.js:110:5)
14 verbose stack     at async Install.exec (/opt/nodejs/node-v22.21.1/lib/node_modules/npm/lib/commands/install.js:150:5)
15 error code EUNSUPPORTEDPROTOCOL
16 error Unsupported URL Type "catalog:": catalog:
17 silly unfinished npm timer reify 1770119044688
18 silly unfinished npm timer reify:loadTrees 1770119044691
19 silly unfinished npm timer idealTree:buildDeps 1770119054325
20 silly unfinished npm timer idealTree:#root 1770119054326
21 verbose cwd /usr/local/lib/node_modules/n8n
22 verbose os Linux 6.12.63+deb13-amd64
23 verbose node v22.21.1
24 verbose npm  v11.7.0
25 verbose exit 1
26 verbose code 1

Thanks for the prompt reply, if you can help me with this then I would love to use your solution instead of my workaround. (I tried other packages by the way, and I get the same error)

Hi @simone-putzu !

Hope you’re doing well.

The error occurs because the npm install command is being executed inside n8n’s directory, which uses pnpm and dependencies with the catalog: protocol—something npm doesn’t understand or support.

In other words, npm and pnpm don’t always play nicely together, especially when pnpm is using special dependency features that npm simply wasn’t designed to handle. :sweat_smile:

Step-by-Step Solution

1. Adjust your docker-compose.yml
Add these two variables below (both are important):

environment:
  - NODE_FUNCTION_ALLOW_EXTERNAL=*
  - NODE_FUNCTION_EXTERNAL_MODULES=fuse.js

NODE_FUNCTION_ALLOW_EXTERNAL=* → allows require()
NODE_FUNCTION_EXTERNAL_MODULES → explicitly tells n8n which modules are valid
Official docs: Code node documentation | n8n Docs

2. Install the package IN THE RIGHT PLACE
Enter the container:

docker exec -it n8n bash

Then:

cd /home/node/.n8n
npm init -y
npm install fuse.js

npm works normally here
No conflict with pnpm
Officially supported

3. Restart the container

docker compose restart

This is important so the Task Runner reloads the environment.

4. Use it in your Code Node (the normal way)
Now this works without absolute paths:

const Fuse = require('fuse.js')

const data = [
  { name: 'Apple' },
  { name: 'Banana' },
  { name: 'Orange' },
]

const fuse = new Fuse(data, { keys: ['name'] })

return fuse.search('appl')

Hi @simone-putzu Welcome!
You need to install your npm package somewhere n8n actually loads modules from, so either install it using npm install to the local node_modules and also set the NODE_FUNCTION_ALLOW_EXTERNAL environment variable or install it to /home/node/.n8n. Do not use the global install via npm, as the n8n image is based on pnpm and it won’t work.