Setting Up an Email Form With Node.js, Express, and Mailgun Part 1

Aidan McBride
9 min readOct 11, 2020


Working on a project for a client, I recently ran into an issue. She wanted her users to be able to fill out a form on her website and have it send her an email without any redirects. Expecting there to be some sort of quick HTML/JavaScript way to solve this, I set out to work. I quickly found out my presumptions about the solution were wrong.

After some hours of learning a bit about Mailgun and Nodemailer, and more about Node and Express, I was able to solve this issue and create a simple functioning email form. I am going to walk through from the beginning of setting up a Mailgun account, to building the Node application, to submitting your email. You may follow this blog better if you have experience with Node.js and/or Express, but I will break everything down step by step. So without further ado, let’s jump into it.

Setting Up a Mailgun Account

Before we do any actual coding we have to set up our Mailgun account. Go to the Mailgun website and sign up for a new account. Depending on the size of the applications you plan to build, I recommend unchecking the payment info box and just choosing the free plan, you can always change your plan later on and upgrade if you need to. The free plan currently allows 5,000 emails for 3 months, which will be much more than enough for our purposes in this tutorial.

There are a few verification steps involved to prevent spammers from creating these email clients, so follow the instructions given to you on the site to verify your account. By default with the free plan you do not have to set up two factor verification, but you can if you want to. If you already have a domain name you can enter that when prompted, however for this example we won’t be using a custom domain.

We will be using npm or node package manager for this tutorial, so first install npm. Run the following command:

install the latest version of node package manager

If you face any errors during this step, refer to the documentation for npm.

Creating Our Application

Now we can begin to build out our Node.js application. Create a folder/directory to work in, I will call mine mailGunApp, cd into that directory and run the following command:

the -y flag automatically answers yes to all the prompted questions

This will create a package.json file. A package.json file lists the packages your project depends on(its dependencies) specifies the version of a package that your project can use, and makes your build reproducible. So, now we can install our first package, Mailgun, using the following command:

install mailgun-js

If we look at our package.json file, you will notice a new dependency has been added on line 13, the “mailgun-js” dependency, followed by its version. If you ever need to know what dependecies a project has, you can always check the package.json file. There is a lot of other information here, such as the application’s name on line 2, and the main file it expects at line 5. For our purposes today we will mainly be focused on the dependencies when looking at this file.

Now, let us create a file to work in, and call it app.js. We should have a node_modules folder, a package-lock.json file, a package.json file, and an app.js file. Our file structure should look something like the image to the right.

Writing The Code

Now that we have our environment all set up, we can begin some actual coding! We will begin by going to and signing in. Once you are signed in, look to the left navigation bar and click on Sending, then Overview. You should be brought to a screen that looks like this:

Important Note: Although I am using a throw-away email address, I have blacked out some personal information for the sake of privacy. Your api key should remain private at all times and not be published on a public GitHub! This will get your account temporarily deactivated until you delete the GitHub repository and reset your password. It is not a fun process, I speak from experience.

Let’s break down this page a little bit. At the top, the Domain selection that I have blacked out is my personal domain sandbox that I was auto generated when I made my account. You can add your own domain if you have own, but for this tutorial we will be using the free sandbox domain that comes with Mailgun.

On the far right you will see Authorized Recipients. You will need to add the email address you plan to be sending email to this list, and keep an eye out for a verification email in your inbox. Once you see the green verified as you do on my screen capture, your email is ready to receive mail.

Finally let us focus on the big API container in the center-left of the page. Click on the Select button and a Menu and some boiler plate code should appear below the container. There are options for which language you want to use, in this case we will be using Node.js on the far right.

Copy the boiler plate code

Once you copy the code and paste it into your app.js file, there are a few changes we can make to make it easier to navigate. First, I find it easier to store your api key in a variable, much like how your domain name is. You can see in your image above your API key(blacked out in my example), it will be a long string of numbers and letters. Your domain name will be everything after In other words it will be something like “”, but likely much longer than that. Make sure you only copy from sandbox on. This can be found next to API base URL, right below the API key.

boiler plate code before you add your own domain and API key

Making Adjustments

The last thing to do is make some minor adjustments to the data object that begins on line 5 in the picture above. The ‘from’ section can be from whoever you want, but making the email enclosed in <> a valid email will reduce the likely hood that your email will get flagged as spam. Change the “to” section to whatever email you verified with Mailgun earlier in this tutorial. If the address is not verified with your Mailgun account it will not send. The “subject” and “text” strings can be whatever you like, so feel free to customize those messages how you like!

Overview of the Code

For the sake of clarity, I would like to briefly walk through each line of code in our app.js file as it appears in the image above labeled “boiler plate code …”. We require mailgun from the mailgun-js package and assign it to a variable ‘mailgun’. Then we assign two string variables, one for our DOMAIN name one for our api_key. Next we assign a variable “mg” to the mailgun function, and pass is it an object containing our api_key and DOMAIN. We next create an object called “data” that will contain all the data of our email, who it’s from, who it’s to, the subject, and text. Finally, we call a function “messages” on the mailgun function or “mg”, we call send on that and pass it data, and a callback function. We pass the callback function error and body and we console log that body to ensure we have have received the data.

If any of that didn’t quite sink in that’s okay, but I do recommend rereading that paragraph and looking at the code until you have a fairly good idea of whats going on. Finally, we are ready to run our code and send our email! If we fill out the data object correctly and run the following command in the terminal:

We should receive some output in the terminal that looks like this:

Your domain or sandbox domain will be in the blacked out section

To ensure everything has gone right, let us first check our Mailgun account. If you select “Sending” from the navigation bar on the right, and scroll down to choose logs, you will be brought to a screen that shows a log of all the messages you have sent or attempted to send via your Mailgun. Scroll down on that page to find the status of your message.

Though they have been blacked out for privacy, the recipient email will be whatever email you verified with your Mailgun service, and the sender email will be whatever email you specified inside your data object in your code. For the final results check your email and there will be a brand new email from your sender!


A couple brief notes about troubleshooting this process. If you find you aren’t receiving emails, you should first check your logs on to ensure that your status is delivered and accepted for your message. The next step is to check your email’s spam folder to ensure that the message was not filtered out. Generally, Mailgun emails end up in spam less often than other mail services, but they still end up there sometimes. Lastly, though Mailgun offers a free account service, there is a noticeable difference between a payed membership and a free account. I have noticed using a free account that the wait period is usually no longer than a few minutes, however, be patient. If you find you are facing issues with receiving mail beyond the scope of this post, I recommend their support department, they usually answer very promptly and can help with any issue.


Do not make a public GitHub repository with your API key or domain url. If you publish a public GitHub repository, your Mailgun account will be temporarily deactivated until you perform the steps necessary to ensure your security. I reiterate this because it is an inconvenient process that you can easily avoid.

Not Out Of The Woods Yet

So we have successfully set up Mailgun to send emails to an address when we run our file! That is cool. That is impressive. But that is not entirely practical. Wouldn’t it be even better if we could send emails from a form on a website? In Part 2 of this blog I will discuss in depth how to create an application using Node and Express that will allow you to fill out a form and send that data directly via email. Enjoy playing around with your new mail client and happy coding!




Aidan McBride

I am a Front End Engineer and graduate of Flat Iron coding bootcamp. Currently I work in the regulatory industry using React.