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.