Best Telegram bot library: python-telegram-bot, aiogram, grammY or Telegraf

In Python, pick python-telegram-bot or aiogram; in JavaScript or TypeScript, pick grammY. All three ship releases often. Telegraf still works, but it has gone a long time without a release.

Updated 6 min read

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
On this page

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.

PythonJavaScriptTypeScriptpython-telegram-botbeginners, JobQueueaiogramasync, FSMgrammYtyping and pluginsTelegraflegacy, move to grammYBot APIthe samefor all
Filter by language, then by the kind of bot; all four talk to the same Bot API with the same limits.

Which criteria matter when choosing?#

  1. 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.
  2. 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.
  3. Maintenance pace. Recent releases mean bug and security fixes keep coming.
  4. 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.
  5. 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):

python
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):

python
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):

js
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):

js
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

Learn more

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.

Next articleWhich database should your Discord bot use?SQLite fits a small single-process Discord bot. PostgreSQL or MongoDB fit when you have several processes, lots of writes or frequent deploys. Here is how to choose.