Skip to content
Guides

How to Create an n8n Custom Node with npm create @n8n/node

In this video

This is the written version of Part 2 of Build your own n8n node. By the end of it, an empty folder has become a node with your name on it, in n8n's search, on the canvas next to Slack and Gmail. It takes one command, and that command is n8n's own, so you're not gluing a project together yourself.

Along the way are the two small mistakes that let a node build without a single error and then never appear. Both come down to one or two lines.

What you need

  • Node.js 22.22.0 or later, with npm. That's the minimum in n8n's docs.
  • A code editor. n8n recommends VS Code with the ESLint, EditorConfig and Prettier extensions, so you see the linter's warnings while you type.

You don't need n8n installed. The tool we're about to use brings its own copy and runs it for you.

One command

In the folder where you keep projects, run:

npm create @n8n/node@latest

This runs n8n-node, n8n's official tool for building community nodes. It asks a few questions.

What is your node called? This becomes the package name, and it matters more than it looks. It has to start with n8n-nodes-, or @your-scope/n8n-nodes- for a scoped package. n8n uses that prefix to recognise a package as a node at all. Get it wrong and everything builds, and the node never shows up, with nothing telling you why. Ours is n8n-nodes-acme-crm.

What kind of node are you building? Choose HTTP API for a node that talks to a REST API. That gives you the declarative style, which is where every node should start. Other gives you a programmatic node; you'd pick it for a trigger node.

What template do you want to use? GitHub Issues API is a finished demo node, useful to read. Start from scratch asks two more questions: your API's base URL, and how it authenticates (API key, bearer token, OAuth2, basic auth, custom, or none). Pick whatever your API uses. Part 4 goes through what the credential file it creates actually does.

Then it installs the dependencies. This is the part where you get a coffee.

What it made

Open the folder and there's a lot in there. Most of it is configuration: TypeScript settings, lint settings, editor settings. You'll rarely open those, and n8n's docs ask you not to edit the lint config at all.

These are the parts that are yours:

n8n-nodes-acme-crm/
├── nodes/            the node itself; you'll live in here for the next few parts
├── credentials/      how a user logs in
├── (an icon)         next to the node file; swap it for your logo
├── package.json      what the package is, and where n8n finds the node
└── .github/workflows/publish.yml   for publishing later, in Part 7

Swap the icon for your own logo early. It's the most satisfying thirty seconds of the whole project. Use an SVG with a square canvas, or a 60×60 PNG, and keep it in the same folder as the node file.

The lines that matter in package.json

Near the bottom of package.json there's a block called n8n:

"n8n": {
  "n8nNodesApiVersion": 1,
  "nodes": ["dist/nodes/AcmeCrm/AcmeCrm.node.js"],
  "credentials": ["dist/credentials/AcmeCrmApi.credentials.js"]
}

This is how n8n knows your node exists: a list of node files and a list of credential files. The paths point at the compiled JavaScript in dist, not your TypeScript. Your copy may hold another setting or two; leave those as the tool wrote them.

Remember this block. If your node stops showing up, look here first. Nearly every time, a file was renamed and this path still points at the old name. n8n doesn't complain. It quietly doesn't load it.

Two more things n8n looks for in the same file, which the tool has already set:

  • the package name starts with n8n-nodes-
  • the keywords list contains n8n-community-node-package

Run it

npm run dev

This builds your node, starts a local n8n with the node loaded, and watches your files. Open http://localhost:5678, sign in to the local instance, open a workflow, press the plus, and search.

Search for the node's display name, like "Acme CRM", not the package name. The panel searches node names, and the two are often different.

And there it is, in the same list as Slack and Gmail and Google Sheets. Ten minutes ago it was an empty folder.

The n8n started by npm run dev keeps its own data, separate from any other n8n you run. Workflows and credentials you make here don't appear anywhere else.

Making changes

While npm run dev is running, saving a code change rebuilds the node, and n8n picks it up. That fast loop is what makes the next few parts pleasant: you can try things.

One exception, from n8n's own troubleshooting docs: changes to the node's description, which includes its fields, labels and options, don't show up on a refresh. Stop npm run dev with Ctrl+C and start it again. If a new field isn't appearing, that's almost always why.

Where you are

Be honest about it: this node is still the template. Inside, it's set up for somebody else's API, or for nothing at all. It looks right, and it does nothing useful yet.

What you have now:

  • the one command that sets up a node project
  • the four parts of it that are yours
  • where to look first when a node doesn't show up: the package name, then the n8n block

Next, in Part 3, the node stops being a template. It gets contacts and deals, operations to pick from a list, and fields that know where they go. Then we press Execute for the first time, and it fails.

One more thing. If your API already has an OpenAPI spec, NativeShip, the tool we build, generates this whole project from it. If you'd rather build it yourself, the rest of this series is for you.

Frequently asked questions

Run npm create @n8n/node@latest in an empty folder. It's n8n's own scaffolding tool. It asks for the package name, the kind of node and how users log in, then creates the project and installs its dependencies.

No. The n8n-node tool brings its own copy of n8n. npm run dev starts it at http://localhost:5678 with your node already loaded. You need Node.js 22.22.0 or later.

Check two things first. The package name must start with n8n-nodes- (or @scope/n8n-nodes-), and the paths in the n8n block of package.json must point at the built node and credential files. Also search the nodes panel for the node's display name, not the package name.

Code changes rebuild automatically while npm run dev runs. Changes to the node's description, such as its fields and labels, need npm run dev stopped and started again.

Ready to launch your n8n, Make, Zapier or Activepieces integration?

Give your customers another way to use your product.

Get started