Learning objectives
After reading this article you will be able to:
- Compare python-telegram-bot, aiogram, grammY and Telegraf on objective criteria
- See the same bot written with each library
- Pick the right library for your scenario
Every Telegram bot talks to the same Bot API over HTTP. The library you choose does not change what your bot can do, but it changes a lot about how you get there: how you register commands, keep the state of a conversation, schedule tasks and keep up with the new features Telegram ships several times a year.
Four libraries show up in most tutorials: python-telegram-bot and aiogram in Python, grammY and Telegraf in JavaScript. Below, each one runs the same example bot so you can compare the code.
Which criteria matter when choosing?#
- Language. This is the strongest filter. Pick the library for the language you already know, because the rest of the bot (database, APIs, business rules) will be much bigger than the Telegram part.
- Bot API compatibility. Telegram ships new Bot API versions often, listed in the official changelog. A stalled library does not expose new types and methods natively.
- Maintenance pace. Recent releases mean bug and security fixes keep coming.
- Built-in features. Multi-step conversations (a state machine), sessions, task scheduling, webhook support and send-rate control. Whatever comes built in is code you do not write.
- Docs and community. For beginners, complete examples are worth more than any advanced feature.
How you receive messages (long polling or webhook) does not decide it: all four support both. The difference is explained in webhook vs long polling.
When should you pick python-telegram-bot?#
python-telegram-bot is one of the oldest and best-known Python libraries for the Bot API. Since version 20 it is built on asyncio. It requires a Python version that is still supported (the minimum is in its docs), and native support for each new Bot API version usually lands a while later. Meanwhile, newer features can be called through the raw API, as its own docs explain.
A bot that answers /start and echoes what it receives (pip install python-telegram-bot):
import os
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes, MessageHandler, filters
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text("Hi! Send me some text and I will repeat it.")
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text(update.message.text)
def main() -> None:
app = Application.builder().token(os.environ["BOT_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
app.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()Pros: extensive docs, a wiki and dozens of examples; ConversationHandler for step-by-step dialogs; built-in persistence; JobQueue for scheduled tasks and AIORateLimiter to respect send limits, both installed as extras (python-telegram-bot[job-queue], [rate-limiter]).
Cons: native support for new Bot API versions tends to lag; libraries that generate their API code automatically get there first. The ordered handlers and groups model needs care as the bot grows.
When should you pick aiogram?#
aiogram is a fully asynchronous Python library whose Bot API integration code is generated automatically. That is why it usually keeps up with new Bot API versions quickly. The supported Python versions are listed on its PyPI page.
The same bot (pip install aiogram):
import asyncio
import os
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart
from aiogram.types import Message
dp = Dispatcher()
@dp.message(CommandStart())
async def start(message: Message) -> None:
await message.answer("Hi! Send me some text and I will repeat it.")
@dp.message(F.text)
async def echo(message: Message) -> None:
await message.answer(message.text)
async def main() -> None:
bot = Bot(token=os.environ["BOT_TOKEN"])
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())Pros: routers to split the bot into modules, a built-in finite state machine (FSM) for forms and conversations, middlewares, "magic filters" (F.text, F.photo) and internationalization support. A good fit for large bots with many flows.
Cons: you need to be comfortable with async/await and decorators from day one. The community is strong, but much third-party material targets the old 2.x line, whose API differs from 3.x.
When should you pick grammY?#
grammY is a JavaScript and TypeScript library with frequent releases, which usually add each new Bot API version shortly after it launches. It runs on Node.js and Deno.
The same bot (npm install grammy, a .mjs file or "type": "module" in package.json):
import { Bot } from "grammy";
const bot = new Bot(process.env.BOT_TOKEN);
bot.command("start", (ctx) => ctx.reply("Hi! Send me some text and I will repeat it."));
bot.on("message:text", (ctx) => ctx.reply(ctx.message.text));
bot.catch((err) => console.error("update error", err.error));
bot.start();Pros: precise TypeScript typing (the "message:text" filter guarantees ctx.message.text exists), very approachable docs at grammy.dev and an ecosystem of official plugins: @grammyjs/conversations for dialogs, @grammyjs/menu for interactive menus, @grammyjs/runner to process updates concurrently with long polling and @grammyjs/auto-retry to retry requests that got a 429. Sessions and webhook adapters for frameworks like Express ship in the core package.
Cons: many features live in separate plugins that you need to know about and install. Older JavaScript tutorials for Telegram tend to use Telegraf or node-telegram-bot-api, not grammY.
Is Telegraf still worth using?#
Telegraf was the default in Node.js for years and it still works. The problem is the pace: the package has gone a long time without a release on npm, and its declared Bot API support is several versions behind. Check the release history before adopting it. Newer methods can still be called with ctx.telegram.callApi, without types.
The same bot (npm install telegraf):
import { Telegraf } from "telegraf";
import { message } from "telegraf/filters";
const bot = new Telegraf(process.env.BOT_TOKEN);
bot.start((ctx) => ctx.reply("Hi! Send me some text and I will repeat it."));
bot.on(message("text"), (ctx) => ctx.reply(ctx.message.text));
bot.launch();
process.once("SIGINT", () => bot.stop("SIGINT"));
process.once("SIGTERM", () => bot.stop("SIGTERM"));Pros: lots of material online, session and Scenes (scenes and wizards) in the main package, an API similar to grammY's.
Cons: Bot API features released after its latest release have no types or helpers. For a new project, that matters. For an existing bot that only uses messages, commands and keyboards, migrating is not urgent.
How do the four compare side by side?#
| Criterion | python-telegram-bot | aiogram | grammY | Telegraf |
|---|---|---|---|---|
| Language | Python | Python | JavaScript/TypeScript | JavaScript/TypeScript |
| New Bot API versions | arrive with some delay | arrive fast (generated code) | arrive fast | stalled several versions back |
| Releases | regular | frequent | frequent | none in a long time |
| Multi-step dialogs | ConversationHandler | built-in FSM | conversations plugin | Scenes |
| Scheduling | JobQueue (extra) | external library | external library | external library |
| Strength | docs and examples | structure for big bots | typing and plugins | legacy material |
Send limits are the same for all of them, because they come from Telegram: per the official FAQ, avoid more than 1 message per second in a chat, at most 20 per minute in a group and about 30 per second for bulk sends. Going over returns a 429 error, the same kind of limit Discord applies, explained in 429 errors and rate limits.
Which one should you pick for each scenario?#
| Scenario | Recommendation |
|---|---|
| First bot, in Python | python-telegram-bot |
| Large Python bot with many flows and forms | aiogram |
| Need the newest Bot API features, in Python | aiogram |
| New bot in JavaScript or TypeScript | grammY |
| Existing Telegraf bot that works fine | Keep it and plan a move to grammY |
| Automating a user account, not a bot | Telethon (MTProto client) |
When in doubt, choose by language, not by library. A well-structured bot in any of the three active options covers most use cases. Once you have chosen, the next step is to keep the process running nonstop, as shown in how to host a Telegram bot 24/7. Keep the token in an environment variable, never in code. If the bot goes silent after deploy, follow the steps in Telegram bot not responding.
How to do this on Square Cloud#
Square Cloud is self-service hosting for bots: you deploy and control the app from the dashboard. It supports python-telegram-bot, aiogram, Telethon, Telegraf and grammY, with long polling that needs no setup, or an HTTPS subdomain for webhooks.
Any of the examples above runs as is: set BOT_TOKEN in the app's environment variables and upload the project as a ZIP, or deploy with the CLI, GitHub or the VS Code extension. The squarecloud.app config file is optional: the dashboard generates it at deploy time, and writing it at the project root is the alternative. Containers stay on, with automatic restart (on by default for dashboard deploys) when the process exits with an error.
All plans are paid and billed in Brazilian reais. Hobby starts at R$12.49 per month, with 1 GB of RAM shared across your apps, and a bot, as a background app, needs at least 256 MB. See Telegram bot hosting.
Bot hosting
Keep your bot online 24/7 with automatic restarts
FAQs
What is the best Python library for a Telegram bot?
python-telegram-bot and aiogram are the two mature options. python-telegram-bot has extensive docs and features such as JobQueue and ConversationHandler; aiogram is fully asynchronous, with built-in routers and a state machine. For beginners, python-telegram-bot is usually easier.
grammY or Telegraf?
For a new project, grammY. It keeps up with new Bot API versions, while Telegraf has gone a long time without a release and declares support for a Bot API several versions behind. Telegraf still works for the basics.
Does the library change Telegram's limits?
No. They all talk to the same Bot API, so the limits are the same: about 1 message per second per chat, 20 per minute in groups and around 30 per second for bulk sends. The library only helps you stay within them.
Can I use Telethon to build a bot?
You can, but Telethon is an MTProto client built mainly to automate user accounts. For a regular bot, a Bot API library is simpler and does not need an API ID or API hash.
More in Bots
See all 33 articles- How much does it cost to host a Discord bot?The cost of hosting a Discord bot depends on RAM, uptime, database and outside services. Learn how to estimate your own bill and where the money goes.
- Running a bot on your phone or PC vs hosting itA bot on your PC or phone (Termux) goes offline when the device shuts down, sleeps or loses its network. Compare the three options and when each one fits.
- How to host a Discord bot 24/7To keep a Discord bot online 24/7, run its process on an always-on machine with automatic restarts. Compare your PC, a VPS with pm2 or systemd, and bot hosting.
- Why your Discord bot keeps going offline (and how to fix it)A Discord bot goes offline when the process dies, the token is invalid, an intent is disabled or memory runs out. Learn to diagnose each cause and fix it.