☰
03.08.2026

How to Build a Telegram Bot in JavaScript and Deploy It on a VPS

Telegram bots are one of the most requested small projects on freelance platforms like Upwork and Fiverr, and building one yourself is far more approachable than it looks. With a basic grasp of JavaScript and an evening to spare, you can end up with a bot that replies to messages, handles commands, and shows custom keyboards.

The tricky part is usually not the code itself, it's what happens after the code works. A bot running on your laptop only works while that laptop is on and the terminal window stays open. Close the lid, and the bot goes silent. To keep a bot answering around the clock, it needs to live somewhere that never shuts down: a server.

This guide walks through the whole process in order. First we'll write a working bot in JavaScript and compare the libraries available for the job. Then we'll move the finished code to a VPS, set it up with PM2, and cover the mistakes that most commonly take a bot offline in its first week.

Why Your Bot Needs a Server, Not Just Your Laptop

It's entirely possible to build and test a Telegram bot on a personal computer, and for development that's exactly what you should do. The problem shows up the moment the bot needs to serve real users. If the process only runs while your machine is awake and connected, every restart, sleep cycle, or closed terminal takes the bot down with it.

A Telegram bot is also one of the lightest things you can host. It doesn't need a powerful machine: a single CPU core and a gigabyte or two of RAM is enough for most personal or small business bots. That makes a basic VPS instance the natural choice, cheap, always on, and independent of whatever is happening on your own computer.

This is exactly the kind of workload a low-cost VPS from Serverspace is built for: instances spin up in about a minute, and the smallest US data center plans are priced for side projects rather than enterprise infrastructure.

What You'll Need Before You Start

Four things, none of them expensive or hard to get.

Getting a Bot Token from BotFather

Before writing any code, the bot needs to be registered with Telegram itself in order to get a token, the credential that lets your code talk to the Bot API.

Open Telegram and search for @BotFather, the official bot used to create and manage other bots. Send the /newbot command and follow the prompts: first a display name that users will see, then a short technical username that must end in "bot".

BotFather then replies with a token, a long string of letters and numbers. This token is the key to the bot: anyone who has it can control the bot as if they were you.

Important: Never commit this token to a public GitHub repository or paste it directly into your source code. We'll cover the right way to store it in the next section.

Choosing a Library: Telegraf vs grammY vs node-telegram-bot-api

It's possible to talk to the Telegram Bot API directly over plain HTTP requests, but that means manually handling every request and parsing every event by hand. A library takes care of that boilerplate.

Three options come up most often for JavaScript bots.

Either of the two actively maintained options works fine for a small or medium bot. Here's a side-by-side comparison to help decide.

Library Popularity Strengths Best For
node-telegram-bot-api Declining, updated infrequently Simple API, but relies on deprecated dependencies Learning exercises only, not recommended for new projects
Telegraf Consistently high, large community Built-in scenes and sessions, rich plugin ecosystem Bots with complex, multi-step conversation logic
grammY Growing fastest, has overtaken Telegraf in downloads Written in TypeScript, lightweight and modern middleware approach New projects and developers who want a current, actively developed stack

This guide uses grammY for the code examples, since it's a solid default for a new project, but the same logic maps almost line for line onto Telegraf if that's the library you'd rather use.

Writing Your First Bot

Create a project folder and initialize it as a Node.js project:

mkdir my-telegram-bot

cd my-telegram-bot

npm init -y

Install the library along with dotenv, which will keep the bot token out of the source code:

npm install grammy dotenv

Create a .env file in the project root and add the token you got from BotFather:

BOT_TOKEN=your_botfather_token

Now create the main file, index.js:

require('dotenv').config();

const { Bot } = require('grammy');

 

const bot = new Bot(process.env.BOT_TOKEN);

 

bot.command('start', (ctx) => {

ctx.reply('Hi! I am a simple JavaScript bot. Send me a message.');

});

 

bot.on('message:text', (ctx) => {

ctx.reply(`You said: ${ctx.message.text}`);

});

 

bot.start();

A quick walkthrough of what's happening. require('dotenv').config() loads the variables from .env, so the token is available as process.env.BOT_TOKEN instead of sitting in plain text in the file. The bot object is created with that token and becomes the entry point for all the logic. bot.command('start', ...) fires when a user sends /start, and bot.on('message:text', ...) reacts to any text message and echoes it back.

Run the bot locally:

node index.js

If everything is set up correctly, the terminal won't print anything, but the bot will already be responding in Telegram. Open a chat with it and send /start, you should get the welcome message back. From here you can add button handling, inline keyboards, or a call to an external API, but this is already a working bot.

Webhooks vs Long Polling: Which One to Use

The code above runs the bot in long polling mode: it repeatedly asks Telegram's servers whether there are new messages. That's the simplest way to receive updates, and it's exactly what bot.start() does by default.

The alternative is a webhook. Instead of the bot asking Telegram, Telegram sends a POST request to a URL you provide whenever a new event happens.

For getting started, and for most personal or small production bots, long polling is a perfectly reasonable default. Webhooks start to make sense once a bot has a meaningful user base and a few seconds of delay actually matters, or when it's already running alongside other services on the same domain.

Deploying the Bot to a VPS

Spinning Up and Preparing the Server

Because a Telegram bot needs so little in the way of resources, almost any entry-level VPS plan will do. Even a bot with a few thousand active users typically runs comfortably on a single core and a gigabyte or two of RAM. It's only worth sizing up if the bot is also doing something heavier in the background, like image processing or frequent queries against a large database.

Any provider can host this, but Serverspace's US plans are worth a look here specifically because their entry-level tier is scoped for exactly this kind of lightweight workload, and the US data center keeps latency low if most of your users are stateside.

Once the server is ready, connect over SSH:

ssh root@your_server_ip

Update the system first:

apt update && apt upgrade -y

Then install the current Node.js LTS release. The NodeSource setup script is the quickest path:

curl -fsSL https://deb.nodesource.com/setup_24.x | bash -

apt install nodejs -y

Check the version:

node -v

If that returns something around v24.x.x, the server is ready for the next step.

Moving the Code and Setting Environment Variables

There are two straightforward ways to get the code onto the server. If the project already lives in a git repository, clone it directly:

git clone https://github.com/your_account/my-telegram-bot.git

cd my-telegram-bot

Without a repository, copy the files from your local machine with scp instead:

scp -r my-telegram-bot root@your_server_ip:/root/

Either way, install the dependencies next:

npm install

One thing to watch for: the .env file usually isn't tracked by git (it belongs in .gitignore), so it needs to be recreated on the server:

nano .env

Paste in the same BOT_TOKEN you used locally. Keeping the token in its own file, separate from the rest of the repository, is worth doing whether the repo is public or private, since it removes the risk of accidentally committing the token along with everything else.

Keeping the Bot Alive with PM2

Running node index.js and closing the terminal kills the process the moment the SSH session ends. Keeping it alive needs a process manager, and for Node.js that almost always means PM2.

Install it globally:

npm install -g pm2

Start the bot through PM2:

pm2 start index.js --name telegram-bot

The process now runs in the background, independent of the terminal. Check its status with:

pm2 status

Last step: make sure it comes back automatically after a server reboot:

pm2 save

pm2 startup

The second command prints an additional line that needs to be copied and run separately, usually a sudo command that hooks PM2 into systemd. After that, the bot will start itself whenever the VPS reboots, with no manual step required.

A few commands worth keeping handy:

Common Mistakes That Take Bots Offline

A handful of issues account for most of the problems new bot builders run into.

Where to Take It From Here

A bot that replies to commands and text messages is a solid starting point, not the finished product. From here, the usual next steps are:

Conclusion

The path from an empty file to a bot running around the clock comes down to a handful of clear steps: get a token from BotFather, write the code with grammY or Telegraf, move it to a server, and run it through PM2 with autostart enabled.

From there, it's easier to grow the bot gradually, adding features as they're actually needed, rather than trying to plan for everything upfront.

A good way to start is to spin up a minimal VPS on Serverspace, deploy the bot from this guide, and see in practice which features it actually needs next.