Using node-cron to Automate Tasks in Node.js
In many projects, there is a need to automate the execution of functions or scripts at specific times. To address this need in Node.js, you can use the node-cron library.
In this article, we’ll cover how to install the package, explore best practices, build a simple project, and deploy it to the cloud.
What Are Cron and node-cron?
Cron is a task scheduler used in Unix-like operating systems (such as Linux) that allows you to automatically run commands or scripts on a schedule. The schedule is written in crontab format, where each line describes the time and command to be executed.
node-cron is a library for Node.js that implements cron functionality directly in JavaScript applications. It allows you to create tasks that run on a given schedule in real-time in a selected time zone, just like classic cron in Unix systems.
Key Advantages of node-cron:
Easy to integrate into existing Node.js projects
Dynamic control over tasks
Supports the same scheduling format as the classic Cron
node-cron Syntax
The syntax of node-cron is similar to traditional cron:
Valid field values:
Field
Values
Seconds
0–59
Minutes
0–59
Hours
0–23
Day of Month
1–31
Month
1–12 (or names)
Day of Week
0–7 (or names, 0 or 7 = Sun)
Using Multiple Values
const cron = require('node-cron');
cron.schedule('1,2,4,5 * * * *', () => {
console.log('Runs at minute 1, 2, 4, and 5');
});
Using Ranges
const cron = require('node-cron');
cron.schedule('1-5 * * * *', () => {
console.log('Runs every minute from 1 to 5');
});
Using Step Values
Step values can be used with ranges or asterisks by adding / and a number. Example: 1-10/2 is the same as 2, 4, 6, 8, 10.
You can also use it after *, e.g. */2 to run every 2 minutes.
const cron = require('node-cron');
cron.schedule('*/2 * * * *', () => {
console.log('Runs every 2 minutes');
});
Using Names for Months and Days
You can use full names for months and days of the week:
const cron = require('node-cron');
cron.schedule('* * * January,September Sunday', () => {
console.log('Runs on Sundays in January and September');
});
Or abbreviated names:
const cron = require('node-cron');
cron.schedule('* * * Jan,Sep Sun', () => {
console.log('Runs on Sundays in January and September');
});
cron.schedule Method
The main method in node-cron is schedule(), which is used to set up a task.
It takes a cron expression, the task function, and an optional configuration object:
scheduled: whether the task is started automatically (Boolean)
timezone: the time zone the cron will follow (String)
Example:
const cron = require('node-cron');
cron.schedule('0 1 * * *', () => {
console.log('Will run at 01:00 Cyprus time');
}, {
scheduled: true,
timezone: "Europe/Cyprus"
});
ScheduledTask Methods
You can manage the state of a scheduled task using:
start() — starts a stopped task
stop() — stops a running task
Starting a task:
const cron = require('node-cron');
const task = cron.schedule('* * * * *', () => {
console.log('Stopped task is now running');
}, {
scheduled: false
});
task.start();
Stopping a task:
const cron = require('node-cron');
const task = cron.schedule('* * * * *', () => {
console.log('Will run every minute until stopped');
});
task.stop();
Setting Up the Working Environment
Let’s set up our environment for working with Node.js and node-cron.
Installing Node.js and npm
To begin local development, you need to install a recent version of Node.js (we recommend v22.14.0 LTS). This will install npm (Node Package Manager).
For Windows:
Go to the official website and download the installer.
Run it and follow the installation instructions.
For Linux / macOS:
In the terminal, run:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
\. "$HOME/.nvm/nvm.sh"
nvm install 22
After installation, verify everything with:
node -v && npm -v
Make sure the versions of Node.js and npm display correctly.
Setting Up the Project Directory
Create a new directory for your project and navigate into it:
mkdir node-cron-project && cd node-cron-project
Initialize the project:
npm init -y
Install node-cron:
npm install --save node-cron
Basic Example of Using node-cron
Let’s build a simple but interesting project using the node-cron library. Our task is to automatically fetch the USD to EUR exchange rate and save the data to a file.
This project is simple, yet it effectively demonstrates how to use node-cron for scheduled tasks.
Installing Additional Libraries
Install additional dependencies for the project:
npm install axios fs
axios — for making HTTP requests (to fetch exchange rate data)
fs — built-in module to work with the file system (to write to files)
Writing the Project
Our app will do the following:
Create a task to fetch the current exchange rate every minute
Write the data to a file called exchange_rates.txt
Log activity to the console
Create a file named index.js and paste in the following code:
const cron = require('node-cron');
const axios = require('axios');
const fs = require('fs');
// Create file if it doesn't exist
if (!fs.existsSync('exchange_rates.txt')) {
fs.writeFileSync('exchange_rates.txt', '');
}
// Function to fetch exchange rate
async function getExchangeRate() {
try {
const response = await axios.get('https://open.er-api.com/v6/latest/USD');
const rate = response.data.rates.EUR;
return rate;
} catch (error) {
console.error('Error fetching exchange rate:', error);
return null;
}
}
// Function to save data to file
function saveData(rate) {
const currentTime = new Date().toLocaleString();
const data = { time: currentTime, rate };
fs.appendFileSync('exchange_rates.txt', `${JSON.stringify(data)}\n`);
console.log(`Rate saved: ${currentTime} - ${rate} EUR`);
}
// Cron job running every minute
cron.schedule('* * * * *', async () => {
const rate = await getExchangeRate();
if (rate !== null) {
saveData(rate);
}
});
console.log('Data collection started...');
Let’s explain what exactly this code does:
if (!fs.existsSync(...)) — Checks if the file exchange_rates.txt exists; if not, it creates it.
getExchangeRate() — Fetches the USD to EUR exchange rate using a public API (in this case, open.er-api.com).
saveData() — Saves the retrieved rate and current timestamp to the file.
cron.schedule('* * * * *', ...) — Sets up a cron job that runs every minute to get and save the latest exchange rate.
Testing the Project
To run your project, execute:
node index.js
You will see this message in the console:
Data collection started...
And a little later you’ll see logs like:
Rate saved: 4/9/2025, 12:00:00 PM - 0.92 EUR
And the exchange_rates.txt file will contain entries with the date, time, and exchange rate.
Using node-cron in a Real Project
Let’s apply node-cron in a practical task. We’ll write a script that automatically sends emails. Companies often use this case to send various promotional content. It’s simple to implement but quite functional.
Getting an App Password
First, we need to obtain a token for your Gmail account:
Log in to your Google Account.
Go to the Security section.
Enable Two-Step Verification. You'll be asked to confirm your identity, for example, via a code sent by SMS. Once enabled, proceed to the next step.
Go to App Passwords to generate a new app password.
Give your app a name (e.g., "nodemailer") and create it.
A modal window will appear with the password. Copy this password and use it in your code.
Writing the Code
First, install the required libraries. Since node-cron is already installed, we only need to install nodemailer:
npm install nodemailer
Now create a file called app.js and write the following code:
const nodemailer = require('nodemailer');
const cron = require('node-cron');
const recipients = [
'recipient1@gmail.com',
'recipient2@outlook.com'
];
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'sender@example.com',
pass: 'PASSWORD'
}
});
function sendEmail(recipient) {
let mailOptions = {
to: recipient,
subject: 'Scheduled Email',
text: 'This email was sent automatically on a schedule using node-cron.',
html: '<b>This email was sent automatically on a schedule using node-cron.</b>'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(`Error sending email to ${recipient}:`, error);
} else {
console.log(`Email successfully sent to ${recipient}:`, info.response);
}
});
}
cron.schedule('* * * * *', () => {
console.log('Running cron job...');
recipients.forEach((recipient) => {
sendEmail(recipient);
});
});
Explanation:
The recipients array contains the list of email recipients.
The transporter variable holds the authentication info for the sender. Replace user with your Gmail address and pass with the generated app password.
sendEmail() is a function that takes a recipient's address and sends an email. mailOptions holds the subject, plain text, and HTML content.
The cron.schedule('* * * * *') task runs every minute, calling sendEmail() for each recipient.
Testing the Application
To run the file, use the command:
node app.js
After a couple of minutes, you’ll see output in the console confirming the emails have been sent. Check your inbox, and you should see the emails arriving.
Deploying the Project on a Cloud Server (Hostman)
After development, we’ll deploy the app to the cloud. For this lightweight mailer, a minimal server setup is sufficient.
1. Install Node.js on your server:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
\. "$HOME/.nvm/nvm.sh"
nvm install 22
Check the installation:
node -v && npm -v
2. Create the project directory:
cd /home && mkdir nodemailer
3. Upload your files (app.js and package.json)
On Windows, use FileZilla.
On Linux/macOS, use:
rsync -av --exclude="node_modules" ./ root@166.1.227.189:/home/nodemailer
Explanation:
--exclude="node_modules" — skip uploading installed libraries
./ — source directory
root@166.1.227.189:/home/nodemailer — target path on the server
4. SSH into the server and verify the files:
cd /home/nodemailer && ls
5. Install dependencies:
npm install
6. Run the script:
node app.js
Check if the emails are being sent correctly. If there’s an issue, make sure port 465 (SMTP) is open on the server. If not, contact support to open it.
To keep the app running even after closing the terminal, create a systemd unit file:
sudo nano /etc/systemd/system/nodemailer.service
Paste the following content:
[Unit]
Description=NodeMailer Service
After=network.target
[Service]
User=root
WorkingDirectory=/home/nodemailer
ExecStart=/root/.nvm/versions/node/v22.14.0/bin/node /home/nodemailer/app.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Note: Adjust WorkingDirectory and ExecStart paths if necessary.
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable nodemailer.service
sudo systemctl start nodemailer.service
Check status and logs:
sudo systemctl status nodemailer.service
sudo journalctl -u nodemailer.service -f
You should see active (running) if everything is working properly.
Service Management Commands
Restart the service:
sudo systemctl restart nodemailer.service
Stop the service:
sudo systemctl stop nodemailer.service
Delete the service:
sudo systemctl disable nodemailer.service
sudo rm /etc/systemd/system/nodemailer.service
sudo systemctl daemon-reload
Conclusion
The node-cron library is a powerful tool for automating tasks on the Node.js platform.
In this article, we created a simple app that retrieves USD to EUR exchange rates and writes them to a file, and we also explored a real-world use case: automatically sending scheduled emails.
We’ve seen how easily node-cron enables you to schedule recurring jobs, from data collection to user interactions. It’s a great choice for developers looking for a reliable and user-friendly scheduling system in Node.js projects.
Its flexibility and ease of use make node-cron an essential tool in any modern backend developer’s toolkit.
15 April 2025 · 10 min to read