node-telegram-bot-api and telegraf are both Node.js libraries designed to interact with the Telegram Bot API. They allow developers to receive updates from Telegram servers and send messages, photos, and other content back to users. While node-telegram-bot-api relies on an event emitter pattern similar to core Node.js modules, telegraf adopts a middleware-based architecture that resembles modern web frameworks like Express. Both libraries handle the low-level HTTP requests required to communicate with Telegram, but they differ significantly in how they structure bot logic and manage state.
Both node-telegram-bot-api and telegraf enable Node.js developers to build bots for the Telegram messaging platform, but they approach bot logic from different angles. One uses a classic event emitter style, while the other uses a middleware pipeline. Let's compare how they handle common engineering tasks.
node-telegram-bot-api uses an event emitter pattern.
message or callback_query.// node-telegram-bot-api: Event-based
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot(token, { polling: true });
bot.on('message', (msg) => {
if (msg.text === '/start') {
bot.sendMessage(msg.chat.id, 'Welcome!');
}
});
telegraf uses a middleware framework.
// telegraf: Middleware-based
const { Telegraf } = require('telegraf');
const bot = new Telegraf(token);
bot.use((ctx, next) => {
console.log('Update received');
return next();
});
bot.start((ctx) => ctx.reply('Welcome!'));
node-telegram-bot-api supports polling out of the box.
// node-telegram-bot-api: Built-in polling
const bot = new TelegramBot(token, { polling: true });
// Webhooks require manual express integration
// bot.setWebHook('https://your-domain.com/bot');
telegraf supports both polling and webhooks easily.
// telegraf: Flexible launch modes
const bot = new Telegraf(token);
// For polling
bot.launch();
// For webhooks
// bot.launch({ webhook: { domain: 'https://your-domain.com' } });
node-telegram-bot-api does not include session management.
// node-telegram-bot-api: Manual state
const userStates = {};
bot.on('message', (msg) => {
const chatId = msg.chat.id;
if (!userStates[chatId]) userStates[chatId] = { step: 0 };
// Handle logic based on userStates[chatId].step
});
telegraf includes a session middleware.
// telegraf: Session middleware
const { session } = require('telegraf/session');
bot.use(session());
bot.on('message', (ctx) => {
if (!ctx.session.step) ctx.session.step = 0;
// Access state directly via ctx.session
});
node-telegram-bot-api has slower update cycles.
// node-telegram-bot-api: Basic method call
bot.sendMessage(chatId, 'Hello', {
parse_mode: 'HTML'
});
telegraf is actively maintained.
// telegraf: Context helper method
ctx.reply('Hello', {
parse_mode: 'HTML'
});
While the architectures differ, both libraries share core capabilities for interacting with Telegram.
// Both: Token initialization
// node-telegram-bot-api
const bot1 = new TelegramBot('TOKEN');
// telegraf
const bot2 = new Telegraf('TOKEN');
// node-telegram-bot-api: Send photo
bot.sendPhoto(chatId, 'path/to/image.jpg');
// telegraf: Send photo
ctx.replyWithPhoto({ source: 'path/to/image.jpg' });
// node-telegram-bot-api: Error event
bot.on('polling_error', (error) => console.log(error.code));
// telegraf: Catch middleware
bot.catch((err, ctx) => console.log('Oops', err));
// Both: Common usage pattern
// Listening for specific commands
// Handling user input
// Managing bot state
| Feature | Shared by Both Libraries |
|---|---|
| Core Protocol | π Telegram Bot API HTTP |
| Auth | π Bot Token based |
| Content Types | π€ Text, Media, Files |
| Keyboards | β¨οΈ Reply and Inline |
| Async Model | β‘ Promise-based methods |
| Feature | node-telegram-bot-api | telegraf |
|---|---|---|
| Architecture | π‘ Event Emitter | π§© Middleware Framework |
| Sessions | ποΈ Manual Implementation | π§ Built-in Middleware |
| Webhooks | π Manual Setup | π Built-in Helpers |
| Maintenance | π’ Slower Updates | π Active Development |
| Context | π¦ Raw Update Object | π― Enriched Context Object |
| Recommendation | β οΈ Legacy/Simple Scripts | β New Production Projects |
node-telegram-bot-api is like a basic utility kit π§° β it gets the job done for simple tasks with minimal setup. It is best suited for legacy systems or quick scripts where adding a larger framework is unnecessary. However, teams should be aware of the slower maintenance cycle when planning long-term roadmaps.
telegraf is like a modern application framework ποΈ β it provides structure, tools, and patterns for building complex bots. It shines in projects that require sessions, multi-step conversations, or integration with other services. For any new development, it is the stronger architectural choice.
Final Thought: While both libraries can send messages and handle updates, telegraf offers a more sustainable path for growth. Choose based on whether you need a quick script or a scalable bot platform.
Choose node-telegram-bot-api if you are maintaining a legacy project that already depends on it or if you need a very simple script with minimal dependencies. It is suitable for straightforward bots that do not require complex state management or middleware chains. However, be aware that active feature development has slowed compared to newer alternatives. It works well for basic notifications or simple command-response bots where architectural flexibility is not a priority.
Choose telegraf for new projects that require a scalable architecture with support for middleware, sessions, and wizard-style conversations. It is the community standard for modern Telegram bot development in Node.js and receives regular updates to support new Telegram API features. The middleware system makes it easier to organize complex logic into reusable components. This package is ideal for production-grade bots that need long-term maintainability and robust error handling.
npm i node-telegram-bot-api
βοΈ Note: If you use Typescript you can install this package that contains type definitions for this library
npm install --save-dev @types/node-telegram-bot-api
const TelegramBot = require('node-telegram-bot-api');
// replace the value below with the Telegram token you receive from @BotFather
const token = 'YOUR_TELEGRAM_BOT_TOKEN';
// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, {polling: true});
// Matches "/echo [whatever]"
bot.onText(/\/echo (.+)/, (msg, match) => {
// 'msg' is the received Message from Telegram
// 'match' is the result of executing the regexp above on the text content
// of the message
const chatId = msg.chat.id;
const resp = match[1]; // the captured "whatever"
// send back the matched "whatever" to the chat
bot.sendMessage(chatId, resp);
});
// Listen for any kind of message. There are different kinds of
// messages.
bot.on('message', (msg) => {
const chatId = msg.chat.id;
// send a message to the chat acknowledging receipt of their message
bot.sendMessage(chatId, 'Received your message');
});
Note: Development is done against the development branch. Code for the latest release resides on the master branch. Experimental features reside on the experimental branch.
We thank all the developers in the Open-Source community who continuously take their time and effort in advancing this project. See our list of contributors.
We have a Telegram channel where we post updates on the Project. Head over and subscribe!
We also have a Telegram group to discuss issues related to this library.
Some things built using this library that might interest you:
The MIT License (MIT)
Copyright Β© 2019 Yago