aiogram: an asyncio framework that keeps pace with Telegram Bot API releases
aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio
At a glance
- What is it?
- A Python 3.10+ Telegram bot framework whose clearest design decision is that its type layer is generated from the Bot API schema, so API support lands within days of Telegram shipping it.
- Who is it for?
- aiogram is the right pick for a team that already lives in asyncio and wants bot development to look like ordinary typed Python. The generated type layer is the part that pays off over a long lived bot: when Telegram ships a Bot API version, the corresponding aiogram release lands within days, and your type checker tells you exactly what changed.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Python 3.10 through 3.14, with PyPy and uvloop as supported extras
The metadata answers the version question precisely. `pyproject.toml` declares `requires-python = ">=3.10,<3.15"` and the classifier list names 3.10, 3.11, 3.12, 3.13 and 3.14, plus PyPy as a supported implementation. The README describes the project as a modern and fully asynchronous framework for the Telegram Bot API written in Python 3.10+ using asyncio and aiohttp.
The runtime dependency list is short and tells you what the framework is actually built on: `magic-filter` for the filter DSL, `aiohttp` for the HTTP client, `pydantic` for the data model, `aiofiles` for async file handling, `certifi` for the CA bundle and `typing-extensions`. Build tooling is hatchling, and the version is read dynamically out of `aiogram/__meta__.py` rather than hard coded in the project file.
There is also a `fast` extra. Its visible contents pull in uvloop on macOS and Linux, excluded on PyPy and on Python 3.13 and above. That version guard is worth noticing, because it means the speedup path is not uniform across interpreters. Installation itself is a single package install, and the related aiohttp dependency comes along with it rather than being something you fetch separately.
Type layer generated from the Bot API schema
The most consequential line in the feature list is that the Telegram Bot API integration code was autogenerated and can be easily regenerated when the API updates. The badge at the top of the README queries `.butcher/schema/schema.json` on the current branch to display the Bot API version the code targets, which is an unusual and rather good transparency move: you can see at a glance whether the library is behind Telegram.
The `.butcher/` directory in the repository tree is that generator's output, and the README links to a separate repository, `aiogram/tg-codegen`, as the tool that produces it. Practically, this means the release cycle is dictated by Telegram rather than by the maintainers' roadmap. The three most recent releases show the pattern.
v3.31.0, published 2026-08-25 and named Telegram Bot API 10.3, adds full support for Bot API 10.3 and also carries a fix for live photo content type detection, a fix for a missing dispatcher contextual argument on the webhook feed path, a fix for the bot level parse mode default not applying to recently added entities, and a dependency bump for a vulnerability. v3.30.0 on 2026-07-17 does the same for Bot API 10.2 and adds testing examples for handlers to the docs. Between them sits v3.29.1 on 2026-07-01, a single bugfix for an exponential slowdown when validating nested unions, which is exactly the kind of failure mode a generated model layer can produce and a hand written one might not.
The feature list as an architecture summary
Read the README's feature bullets as a description of the runtime, and the design becomes clear. Updates are dispatched through a router, referred to in the README as Blueprints, meaning a bot can be split across modules rather than living in one file. Filters use magic filters, a small expression language rather than a collection of predicate callbacks. Middleware exists on both sides of the boundary: incoming updates and outgoing API calls.
Two of those deserve comment. Middleware on API calls is what lets you log, rate limit or mock every outbound request in one place, which matters for a bot that talks to Telegram hundreds of times a minute. Magic filters are a comprehension trade: readable conditions in exchange for learning a DSL, and the `examples/own_filter.py` file in the tree is there precisely so you can write your own.
Finite state machine support is listed as a built in feature rather than an add-on, and the examples directory backs that up with `finite_state_machine.py`, `scene.py` and `quiz_scene.py`. For a bot that collects an order or walks someone through a signup, that is the difference between a linear chain of if statements and something with structure.
Internationalisation uses GNU Gettext or Fluent and is listed as integrated rather than bolted on. v3.31.0 includes a fix to resolve territory specific locales from Telegram's language code, which tells you the framework maps the user's Telegram setting to a catalogue rather than asking the bot to do it.
The examples directory maps directly onto real bot shapes
Sixteen entries in `examples/` is a good sign for a framework, because it means the project answers questions about architecture rather than only about syntax. Reading the names tells you which patterns the maintainers consider normal.
`echo_bot.py` is the floor. `echo_bot_webhook.py` and `echo_bot_webhook_ssl.py` add the deployment path, and the framework advertises replies into webhook support, which lets a bot answer an inline query or a shortcut inside the reply to a message instead of a separate call. `multibot.py` covers running several bots in one process, and `without_dispatcher.py` shows the low level path for when you want to skip the router entirely and drive the API client yourself.
The rest are domain patterns. `stars_invoice.py` handles Telegram Stars invoicing. `specify_updates.py` restricts which update types a bot requests, which reduces load. `context_addition_from_filter.py` shows how a filter injects data into the handler context. `error_handling.py` is the one to read before production, since an unhandled exception in a bot framework usually means a silent dead handler. There is also a `web_app/` directory for Telegram Mini Apps, a `data/` directory, and a `multi_file_bot/` directory which is the canonical answer to how to split a growing bot across modules.
A Makefile that documents the project's own standards
The repository is opinionated about tooling in a way that is worth reading even if you never run it. `Makefile` sets the default goal to lint and defines the layout with variables for the package, tests, scripts and examples directories. The install target cleans first, then syncs everything:
uv sync --all-extras --group dev --group testLint is three tools, not one:
uv run ruff format --check --diff aiogram
uv run ruff check --show-fixes --preview aiogram examples
uv run mypy --native-parser --num-workers 8 aiogramRunning `ruff format` in check mode with a diff means formatting is enforced as a reviewable change rather than silently applied, and `ruff check` with `--preview` opts into rules that are still settling. `mypy --native-parser` matters here in a way it would not in an ordinary project: the model layer is generated, and a fast parser keeps type checking that layer usable.
The test section sets `redis_connection` and `mongo_connection` variables, which suggests integration tests cover storage backends rather than only the in memory cases. The `uv.lock` file and the presence of `codecov.yaml`, `.pre-commit-config.yaml` and `CITATION.cff` round out a project that publishes its process as well as its code.
Where the README stops and aiogram.dev begins
The README is honest about its own limits. It describes the project, lists features, points at the English and Ukrainian documentation sites and links to six community chats on Telegram, in English, Ukrainian, Uzbek, Kazakh, Russian, Persian, Italian and Brazilian Portuguese. Beyond that it does not attempt documentation.
That boundary is normal for a framework of this size, and the documentation URLs are versioned rather than floating, with paths like `/en/dev-3.x/` and `/uk_UA/dev-3.x/`. The default branch is `dev-3.x`, which means the 3.x line is the one being worked on, and the version segment in the docs URL lets you pin the documentation to the same line your installed package is on.
Two files in the tree are worth knowing about before you dig in. `AGENTS.md` and `CLAUDE.md` both appear at the top level, which tells you the project has formalised instructions for automated coding assistants as well as for human contributors. `openspec/` suggests a specification directory maintained alongside the code, and `CHANGES/` sits next to `CHANGES.rst` and `HISTORY.rst` for the release history.
The repository is not archived and the last push was on 2026-09-19, three weeks after the Bot API 10.3 release, so the code generation loop is running.
Editorial conclusion
aiogram is the right pick for a team that already lives in asyncio and wants bot development to look like ordinary typed Python. The generated type layer is the part that pays off over a long lived bot: when Telegram ships a Bot API version, the corresponding aiogram release lands within days, and your type checker tells you exactly what changed. The price is a genuine learning curve in the dispatcher, filters and middleware model, which is why the README carries an explicit warning that prior asyncio experience is strongly advised. Start at aiogram.dev with the English or Ukrainian docs, work through `examples/echo_bot.py` and `examples/finite_state_machine.py` in the repository, and read the 2.x to 3.x migration guide before reading anything else if you are porting an older bot.
Frequently asked questions
What version of Python is Aiogram written in?
aiogram requires Python 3.10 or newer, with `pyproject.toml` declaring `requires-python = ">=3.10,<3.15"` and classifiers for 3.10 through 3.14. PyPy is listed as a supported implementation. The optional `fast` extra installs uvloop on macOS and Linux, but skips it on Python 3.13 and above as well as on PyPy.
How do I install aiogram and aiohttp?
aiogram is installed as an ordinary package and brings aiohttp with it, since aiohttp is a required runtime dependency rather than something you add yourself. The framework also depends on magic-filter, pydantic, aiofiles, certifi and typing-extensions. Installation instructions are on aiogram.dev, and the repository's own Makefile shows the maintainers' development setup using `uv sync --all-extras --group dev --group test`.
Does aiogram support both long polling and webhooks?
Yes, and both paths have examples in the repository: `echo_bot.py` for the default polling model and `echo_bot_webhook.py` plus `echo_bot_webhook_ssl.py` for the HTTP path. The README also lists replies into webhook support, which lets a bot respond inside a message reply rather than through a separate request, and v3.31.0 fixed a related bug where dispatcher contextual data was missing on the webhook feed path.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/aiogram-aiogram)Was this useful?