n8n Tutorial #7: Create your own Custom Node

10.06k views4140 WordsCopy TextShare
Ben Young AI
Sign up for a 14-day free trial of n8n Cloud: https://smarterchats.com/go/n8n Queue Mode on Railway ...
Video Transcript:
Hey integrators! If you've used n8n for some time,  you may run into a situation where n8n doesn't have a native node for your use case and there's  no suitable community node available. This is where building your own custom node may be a good  option to solve your unique business problems.
I'm going to show you exactly how to create your own  custom n8n node in this video, step by step. Let's go! From my last video about using community nodes  and custom code, which you can see here, I want to give a shout out to bannu4832 for suggesting  that I make this video.
They mentioned that all the videos and docs showing how to do this are  outdated. And after taking a look, sure enough, the most recent video showing how to do this is  over 2 years old. And from the recent feedback in the comments, no one could make it work.
They  even changed the title to say, out of date. I also found that following n8n's most current  custom node documentation doesn't work either, which is frustrating for anyone trying to figure  it out. Even the most current and reliable n8n resources don't show how to successfully do this. 
So I'm really excited to make this video to help everyone out. I'd appreciate it if you could hit  the like button for this video for the work that went into creating this. It's a great free  way to help support me and my channel.
Also, if you want to save yourself time and effort, I'm  available to build custom nodes or n8n workflow automations for you. You can reach out to me using  the link in the description. So what are your options if no native n8n node and no community  node exists for what you want to do?
Well, there are three options. You can use the HTTP  request node if you're making an API call, which I covered here. You can use the code node to  run custom Python or JavaScript code, which I also covered in my last video.
Or you can create your  own custom n8n node. While this last option can be more complex and time consuming than the other  options, there are some advantages to doing this. It's easy for you and others to integrate and use. 
If you choose to upload it as a community node, you can make use of it on any self hosted instance  of n8n. This is a simple workaround if you're hosting it on railway and want to install a custom  package. But keep in mind that sharing it on the NPM registry also makes it available to everyone  else.
Now, adding it as a community node isn't mandatory. You can keep the node private, but  you would need to install it through the rpm run build method, which I'll show you in a minute. It  allows users to add their own credentials instead of having the credentials hard coded in your  code.
I'll show you how this works in this video. It allows you to create a user interface that  abstracts and exposes to the end user only what you want them to see. When I create automations  for my clients, I often create them so I can run them internally within my company.
But sometimes  my clients want to run them manually themselves. Creating a custom node that caters to their needs  and nothing more can be a good way to do this. For example, we've been building a workflow that gives  the current weather of a city simply by specifying the name of that city.
However, the city weather  map node has a lot more inputs than just the city, and giving a client access to all these options  may actually result in them screwing something up. Creating a custom node for them that only exposes  the inputs we want them to access can be really useful. Lastly, I should mention that custom  created nodes are not currently supported by n8n's cloud service for security reasons.
They only  work for your own self-hosted instances. Okay, I think that's enough background for now. Let's  get started on building our own custom node.
There are two types of styles of n8n custom  nodes available. Declarative and programmatic. n8n has provided a starter template for both of  these types.
You would use a programmatic style for any of the following. If you're creating a  trigger node. If you're accessing an API that's something other than REST-based, so for example  GraphQL.
Any node that needs to transform incoming data. And you need full versioning. But in this  video we're going to be covering the declarative type, as it's what is used for most nodes and  it's more future proof.
So I'm going to loosely follow n8n's declarative style node tutorial to  create my custom node. However, their tutorial queries the NASA API for pictures from space. And  in my node I'm going to query the current weather for a given city using the Open Weather Map API. 
In order to remain consistent with the previous videos in this tutorial series. For the most part  I follow the same steps as the tutorial. But I'll show you what changes I had to make to get my  code to work.
So the first step is to download or clone the template of the declarative style  repository. And you can get that at github. com, n8n-io, n8n-nodes-starter.
Now you can git  clone the repository, but I'm just going to download the zip file directly. So we save that  and I'm just going to extract the file. And then I'm just going to rename the folder so that  it's n8n-nodes-cityweather.
Now if I open up this folder in Visual Studio Code. We'll see on  the left here there's actually two folders that we need to pay attention to. And that's nodes  and credentials.
And if I open up nodes you'll see there's already two folders here. One called  example node and the other called HTTP bin. And these are actually examples that they include in  the starter template.
And same with credentials there's two files here. You can take a look at  these if you want but what I'm going to do is I'm actually going to delete these. So I'm going to  choose delete.
Move them to trash. And same with the credentials. I'm going to delete those as well  and move them to trash.
So now we have two empty folders. The nodes folder and the credentials  folder both with no files in them. In the nodes folder I'm going to create a subfolder called  cityweather.
So in this cityweather subfolder we want to create two files. So the two files we want  to create. The first one is cityweather.
node. ts. And the second file is cityweather.
node. json. And  then in the credentials folder we want to create a new file called cityweatherapi.
credentials. ts.  Now the last file I'm going to add is just an SVG file.
And it's the icon that will appear. And so  I just found this on the internet. It's just for an example.
And I named it openweather. svg and  that's how the icon looks like. So in the end, in the credentials folder you should have one file  called cityweatherapi.
credentials. ts. And in the nodes cityweather subfolder you should have three  files.
The node. json file, the node. typescript file, as well as the icon openweather.
svg. So if  I go back to the n8n tutorial, I'm just going to copy and paste some of the code that they've given  us. The first one is start by adding the import statements.
So I'm going to copy this. I'm going  to go back to Visual Studio Code and I'm going to go to the cityweather. node.
typscript file. I'm  going to paste that in. Then I'm going to grab the main class.
So I'm going to copy this code  here and paste that in as well. But because I called mine cityweather, I'm going to change this  from nasapics to cityweather. Then the next step in the tutorial is to add the node details.
So  instead of copying all of this code because it's all labeled as nasa. pics, I already had copied and  pasted this into a previous file. But in this case I named everything cityweather.
So I'm just going  to copy this. But it's basically the same thing as what's in the tutorial except everything's  been relabeled as cityweather. And I changed the base URL to be the open-weather-map API URL. 
So I'm going to copy that and I'm going to paste that right under here. Now the next step in the  tutorial is to add resources. Now resources is what displays in the user interface in n8n.
And my  resources are going to look different than what's here in this nasa. pics example. So I'm going to  go back to the code that I have that I've created.
And in my code, you can see here I've labeled  this as required fields. So the only field that I'm requiring is that the user enters a city name.  And then down below there's optional or additional fields.
And so in n8n in the user interface,  oftentimes there's a button that says additional fields or additional parameters. And if you click  that, you can add the optional parameters. So my optional parameters are there's the format.
And  so the format, the different options for format are imperial, metric or scientific. But that  will be a dropdown that will give the user the three different options to choose from. And  that's actually going to create my units.
And the default value is metric. Then the other  option that I have here in additional fields is the language. So I'm just going to copy all of  this.
The optional fields and the required fields. And then under properties on the file that I've  created, I'm going to highlight everything in properties, delete that. And then paste in  everything that was in my file.
And then I'm going to save this file. Now step four in the  tutorial is to set up authentication. And this is where you edit the city weather credentials dot  TS file.
And I can basically copy all of this code as is. And then I go to my credentials file, which  is under the credentials folder under city weather API credentials dot TS. And I'm going to paste in  everything that I got from the tutorial.
The only thing I'm going to change here is the name. So  instead of NASA picks API, it's city weather API. And I'm just going to change the display name to  say city weather as well.
And the last thing I'm going to change in this file is if you recall from  the API documentation from Open Weather Map. This API key title is not called that. And actually  I'll go to the documentation.
And if I click down here to built in API request by city name, which  is this URL that we want. The API key is actually called app ID, all one word. So that's what we  want for this API.
So in the file, I'm going to change API key to app ID. And that's basically it.  So I'm going to save this file.
So then step five in this tutorial is to add node metadata. So this  is the cityweather. node.
json file. And it's quite simple. I can copy this code again, go back to my  VS code and then open the cityweather.
node. json file and paste that in. And the only thing I'm  going to change here is instead of NASA picks, I'm going to call it city weather.
And everything  else stays the same. So I'll save that file. Now, the last step, step six in this tutorial is to  update the NPM package details.
And so there's a whole bunch of code here. And here's the big  glaring issue that causes the current n8n custom node documentation to fail. Back in July 2024,  they switched the starter template to use pnpm instead of NPM to match the package manager that  n8n uses.
You can see this pull request number 41 here, and it says replace npm with pnpm. And  actually, if I click on #41, it actually replaces #39. And if you go back to 39, it says to match  the package manager n8n uses.
So while I think switching to PNPM is a good decision overall, the  starter templates would simply not work if you tried to follow the existing tutorials. Since the  package. json file forces you to use PNPM, which causes the tutorial to totally fail.
It has to do  with the NPM link command. I tried to make it work with pnpm, but it was just too much of a headache.  So the way I made it work was to revert back to a previous version of the package.
json file before  July 2024. So you can still use NPM to build the custom node. So if I go to this package.
json file  in the n8n node starter template, click on that. You can see here that there's history in the top  right here. And if I click on history, the version right before this change to replace NPM with PNPM  is from May 2nd, 2024.
And if I go to the right here and on this icon that says view code at this  point and I click on that, it'll actually show me the package. json code that was from May 2nd,  2024. So if I actually copy all of this and I go back to my VS code and open package.
json here.  So I'm actually going to highlight all of this and delete it and then paste in the package. json code  that was from May 2nd, 2024.
And I just need to change the names for anything that's like dot dot  dot. So this one is called city weather and the GitHub doesn't matter so much. So I'm just going  to change this to city weather, Ben Young.
And I think that's all we need to do here. So I'm  going to save this file. The other thing that you can do is you can delete this pnpm dash lock  dot yaml file as we're no longer using pnpm.
OK, so we can now test our node and there's really  just a few steps that we need to take. The first step in the documentation is to make sure that  n8n is installed. So that's using the command NPM install n8n-G.
I already have it installed, so I'm  going to skip this step. So the next step is to run these two commands in the folder that you just  created for city weather. So I've opened up my n8n nodes city weather directory here.
And you can see  in this file there is that package. json. There's the credentials folder as well as the nodes  folder.
So that contains everything that I just created. The first thing we need to do is we need  to NPM I or install. And that'll add all the node modules to this project based on the package.
json  file. So once that's installed, we can go and then run these commands from this step. So the first  one is NPM run build.
So I'll type in NPM run build. And then the next step is run NPM link.  So I'll type in NPM link.
And that's done. So the next step after that is to install the node into  your local n8n instance. And that's the NPM link and then the node package name.
And in our case,  the node package name is n8n-nodes-cityweather. So we need to go to our local n8n instance. And so on  a Mac or Linux, that would be cd and then the root of the user directory forward slash dot n8n.
And I  think for Windows it would be C drive slash users slash your user name and then forward  slash dot n8n. So I'll go into that folder. So if I look at my present working directory,  it's users Ben Young and then dot n8n.
And this is how my folder looks like. Now notice that there  is a little highlighted section here that says check your directory. Make sure you run NPM link  node name in the nodes directory within your n8n installation.
So the default here is n8n custom.  Now, if you look at my directory listing here, there is no custom folder. And if we scroll  down a little bit further in this tutorial, there's a troubleshooting section that says  there's no custom directory in the n8n local installation.
And it says you have to create  custom directory manually and run NPM init. So in the n8n directory, you make a custom directory,  change directory into it and then run NPM init. So I'm going to make directory custom.
I'm going  to change into that directory. And then I'm going to run NPM init. And so this just creates  a package.
json file for you. So the package name, I'm just going to use all the defaults here.  So custom version one, the description, I'll just say custom nodes, but really it doesn't  matter.
Entry point, I'll use that as the default test command. I'll press enter, keep pressing  enter. And I'll say, yes, this is OK.
So if I look at this directory again, now it's created  this package. json file for me. And I indeed have the n8n and a custom folder now.
So now I can go  back to the test your node steps and run this NPM link and node package name. So I'm going to type  in npm link and my node package name was n8n nodes dash city weather. And we can see one package  was added.
So now if I run n8n. And then I go to my browser to that instance and I refresh the  browser. So let's add a workflow.
And I'm going to click this plus button. And if I type in weather,  we can see that there's the open weather map node, but also the city weather node that I made. And  that's the app icon that I created.
So if I click on this, we can see that there's a credential  that I've previously I already connected it. And then there's the placeholder Honolulu. But  if I click into it, I can type in Denmark.
And then you can see there's additional fields. And  so if I click add field, we can choose between format and language. So format and there's three  selections here, imperial, metric and scientific.
Note that metric is the default. And then I can  add another field, which is language. And here I can type in EN if I wanted to, or I could just  delete that.
So let's test this step and see what happens. And there we go. There's the output. 
And there's the name Denmark. We can see that it's 15 degrees. And if I go back to Visual Studio  Code and we look at the city weather node file, we can see that my display name is city weather. 
It uses the credentials from the city weather API, which is the other file that I had created, which  is city weather API credentials. The API base URL is the one that is from open weather map dot  org. And this is the property.
The property is city. And so if I go back, we can see that  this is what this is, city. The description is the name of the city to return the weather of.
And  if I go here, the question mark is the name of the city to return the weather of. The placeholder was  Honolulu. Otherwise it's blank.
Required is true. And this routing is important. It's where the  request is put and it builds the query string.
And that's this QS and Q is then the value. And this  value is what is entered here. And if you recall, this Q is actually if we go back to the  documentation, the Q is the city name that's entered in that query string.
And so that's why I  put Q here. And these are the optional additional fields. So that's what we saw here.
Right.  Format. And then the three options, imperial, metric or scientific.
And the first option is  format. And then there's the three options, imperial, metric or scientific. The default is  metric.
And then there's a description here, which also reflects here. And here we're building  the query string. So the query string is units.
And again, it's entering the value that's selected  in that dropdown list. So one of these three. And this units corresponds with the optional units,  which is right here in the documentation.
And they have standard, metric or imperial units  that are available. And then the last option we have here is language. And so the placeholder  is English or EN.
And there's the description. And then we build the query string here. And it uses  lang, which if we go back, there's the optional parameter lang.
So if I was to delete this format,  since it's set up as an optional parameter. And I was to type in Winnipeg and I was to test this  step. Then we would see that the city is indeed Winnipeg.
But if we look at the temperature, it's  two hundred eighty six point seven nine, which is using the default standard units. So if you  want to make any changes to your custom node, all you have to do is rerun NPM run build in your  n8n node's city weather directory. And then NPM link and the package name in your n8n instance. 
And then that'll reflect any changes that you make. So, for example, if we wanted to make  the format like I had just mentioned mandatory, what I would do is in the code, I would  take all of this here, which contains all the options for the format. And you can see  the three things here.
If I cut that out. And then I paste it in the required fields. So right below  the city, I add in the format and I save that file.
And then in the city weather nodes, I would  run NPM run build. Let that run. Once that's done, I would then go and in my instance in the  custom folder, I would say NPM link and then n8n dash nodes dash city weather.
Enter. Let  that make the changes. And then I run n8n.
And if I go to my n8n instance and I just reload the  browser here, I'm going to delete city weather and I'm going to add that in. Weather. Add this  in.
And there we go. We can see that format is a mandatory field now and metric is the default. And  so that reflected the change that we just made.
So congratulations, you created your own custom node.  The last yet optional step would be to publish this custom node to the NPM registry. That's a bit  beyond the scope of this video, but you can find details on how to do this here.
One final thing  I want to mention about creating a custom node. There's no need to reinvent the wheel. n8n shares  all of its source code on GitHub.
So use it to see how each node is built. If you want to do  something that you've seen in an existing node, you can go into the code and see how it's done.  For example, the open weather map node source code shows us how the node UI is constructed.
So  building a declarative custom node can go beyond these JSON tags here. You can see at the bottom  of this node, there's a lot of JavaScript as well, which offers a lot of flexibility. So in this  video, we looked at reasons why to create a custom node in n8n.
Then we created a simple  declarative style node ourselves using the starter template. I've saved the n8n custom code  that I used in this video, which you can access in my AI integrators community. It's completely  free to join and you can access it using the link in the description.
Also, if you're interested  in building your own custom node or n8n workflow automation and want to save yourself the time and  effort, I'm available to consult or build them for you. You can reach out using the link in the  description. Please remember to like this video and check out my next video in this tutorial  series, where we start looking at some of the powerful AI features that n8n has to offer.
Thanks  for watching and I'll see you in the next one.
Copyright © 2025. Made with ♥ in London by YTScribe.com