Library / SDK
telegraf/telegraf avatar
telegraf/telegraf

Telegraf (Node.js): a Telegram bot framework with typed middleware

Modern Telegram Bot Framework for Node.js

9,194 stars939 forksTypeScriptMIT

At a glance

What is it?
Telegraf is the JavaScript and TypeScript framework for building Telegram bots, with full Bot API 7.1 coverage and a Context object at the centre of every handler. This review covers what it solves, how the middleware pipeline works, how to install it, and where it stops being the right tool.
Who is it for?
Adopt Telegraf if you are building a Telegram bot in JavaScript or TypeScript, you want typed handlers and a middleware chain instead of hand-rolled update dispatch, and you can live with the Bot API 7.1 coverage the README advertises. Do not adopt it if your stack is not Node, or if your bot is a few API calls with no routing.
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 7 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Telegraf solves, and who actually needs it

A Telegram bot is a Telegram account whose replies come from code on your own server. The Bot API itself is an HTTP endpoint: you poll it or receive webhooks, parse JSON, and dispatch each update yourself. Telegraf is the layer that removes that plumbing. It obtains updates, builds a Context object per update, and runs your handlers in order.

The intended audience is narrow and clear. If you write JavaScript or TypeScript and you want a bot rather than a bot-shaped HTTP client, this is the project's target. The README states full Telegram Bot API 7.1 support and calls out TypeScript typings as a first-class feature, which matters because update payloads are deeply nested and easy to misread without types. The framework also advertises compatibility with AWS Lambda, Firebase, Glitch, Fly.io and generic http/https servers, plus fastify, Connect.js and express.js webhooks. That list tells you the authors expect deployment to vary, and they did not tie the library to one runtime.

What it is not: a hosted service, a bot builder, or a database. You still register with BotFather, you still store the token, and you still own uptime. Telegraf only owns the part between an incoming update and your reply.

How the middleware pipeline and Context object fit together

The architecture is a middleware chain, and the README describes the division of labour precisely. A Telegraf instance represents your bot and is responsible for obtaining updates and passing them to your handlers. Each incoming update gets one Context instance, created by Telegraf and passed to your middleware. That Context carries the update, botInfo, and a telegram object for arbitrary Bot API requests, plus shorthand methods and getters.

So there are two ways to call the API, and the README shows both side by side. You can go explicit with ctx.telegram.sendMessage(chatId, text), or use the shortcut ctx.reply(text). The same pattern holds for leaving a chat (ctx.telegram.leaveChat(chatId) versus ctx.leaveChat()) and for answering a callback query (ctx.telegram.answerCbQuery(id) versus ctx.answerCbQuery()). The shortcut is not a different code path; it is a convenience wrapper over the same client.

Routing is where the framework earns its place. Handlers are registered with bot.command, bot.hears, bot.start, bot.help, or bot.on with a filter. The filters module is a separate entry point, imported as telegraf/filters, and it lets you write bot.on(message('sticker'), ...) or bot.on(message('text'), ...) instead of matching on raw update fields. Because handlers run in registration order, the position of a broad bot.on handler relative to a specific bot.command handler changes what your bot does. That ordering rule is the single most important thing to internalise, and it is the source of most confused bug reports about middleware frameworks in general.

The package also exposes separate entry points for scenes, session, markup, format, utils, types and future, each with its own type definitions. That layout is visible in package.json exports, and it means you can import only what a given file needs rather than pulling the whole surface.

Installing Telegraf from npm and launching a first bot

Before any code, you need a token. The README says to get a bot account by chatting with BotFather, who returns a token shaped like 123456789:AbCdefGhIJKlmNoPQRsTUVwxyZ. Treat that string as a secret and keep it in an environment variable.

Installation is a single package manager call. The README lists npm, yarn and pnpm as equivalent options:

bash
npm install telegraf

A minimal bot then needs the Telegraf class, a handler or two, and a launch call. This is the README's own example, kept short:

js
const { Telegraf } = require('telegraf')
const { message } = require('telegraf/filters')

const bot = new Telegraf(process.env.BOT_TOKEN)
bot.start((ctx) => ctx.reply('Welcome'))
bot.help((ctx) => ctx.reply('Send me a sticker'))
bot.on(message('sticker'), (ctx) => ctx.reply('👍'))
bot.hears('hi', (ctx) => ctx.reply('Hey there'))
bot.launch()

Run that with BOT_TOKEN set, and the bot answers /start, /help, any sticker, and the literal text hi. If nothing responds, the usual cause is a missing or malformed token rather than a code error.

The README pairs every launch with graceful shutdown, and this is worth copying rather than skipping:

js
process.once('SIGINT', () => bot.stop('SIGINT'))
process.once('SIGTERM', () => bot.stop('SIGTERM'))

Without it, a redeploy can leave the old process holding the update stream. Telegraf also ships a command line entry point: package.json declares a bin named telegraf pointing at lib/cli.mjs, so the package installs an executable as well as a library.

Where Telegraf is the wrong choice

The first limitation is the runtime. Telegraf is a Node.js library, and the README frames it that way throughout. If your team writes Python, Go, PHP or Rust, this project offers nothing, and you should look at a bot library in your own language instead of running a Node process purely to host the bot.

Second, the Bot API version is pinned in the badge to 7.1 while the most recent release listed is v4.16.3 from 2024-02-29. Anyone who needs a Bot API feature added after that point should check the repository rather than assume it is present. The README does not document a compatibility table for newer API revisions.

Third, the middleware model is not a workflow engine. If your bot needs durable multi-step conversations that survive a restart, Telegraf gives you a Context and a session entry point, but persistence is your problem. The README's own commented-out list of known middleware points at third-party packages for internationalisation, Redis sessions, local sessions, rate limiting, throttling, inline menus and stateless questions. Each of those is a separate dependency with its own maintenance, and the list is marked with a TODO to verify and update. Read that as an admission that the ecosystem around Telegraf is not curated by the core project.

Finally, if your bot is a thin proxy over a handful of API calls with no routing logic, the framework is more structure than you need. A direct HTTPS call to the Bot API would be shorter and would remove a dependency you have to upgrade.

Telegraf against node-telegram-bot-api and raw Bot API calls

The README itself compares install size against node-telegram-bot-api through a packagephobia badge, so the two are treated as peers. The real difference is not size but typing and routing.

node-telegram-bot-api is the older, widely deployed Node client. It exposes events and API methods in a style closer to the raw Bot API, and its TypeScript support has historically been thinner. Telegraf's 4.0 release notes, linked from the README, present improved TypeScript typings as a headline change, and the package ships .d.ts files for every entry point. If you write TypeScript and want the compiler to catch a wrong field on an update, that difference is the whole argument.

The second alternative is calling the Bot API directly. There is no framework, no middleware, no Context, and no dependency to upgrade. You write the polling loop or the webhook handler, and you dispatch updates with your own switch statement. That is a reasonable choice for a bot with three commands, and it becomes painful the moment you add filters, sessions or per-chat state, because you end up rebuilding a smaller version of Telegraf with fewer tests.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-09-24. That is recent, but the release history is older: v4.16.3 shipped on 2024-02-29, preceded by v4.16.2 on 2024-02-26 and v4.16.1 on 2024-02-25. So commits continue while tagged releases have not. Anyone who depends on published versions rather than the branch should account for that gap, and anyone tracking the default branch should note that it is v4, not main.

The licence is MIT, declared in both the README repository metadata and package.json. MIT permits commercial and closed-source use with attribution and without copyleft obligations on your own code. This is a description of the licence text, not legal advice; if your organisation has specific compliance requirements, have counsel read the LICENSE file at the repository root.

Upgrade cost is shaped by the version history. The README keeps a dedicated section for 3.x users pointing at the 3.x docs and the 4.0 release notes, which tells you the 3 to 4 transition was significant enough to warrant its own migration path. Expect the same class of work at the next major. Within a major line, the separate entry points (filters, scenes, session, markup, format, utils, types, future) mean a breaking change in one area does not necessarily force a rewrite of the rest.

Editorial conclusion

Adopt Telegraf if you are building a Telegram bot in JavaScript or TypeScript, you want typed handlers and a middleware chain instead of hand-rolled update dispatch, and you can live with the Bot API 7.1 coverage the README advertises. Do not adopt it if your stack is not Node, or if your bot is a few API calls with no routing. Before committing, verify two things: whether the Bot API features you need exist in the current source, given that the newest release listed is v4.16.3 from 2024-02-29, and whether the third-party middleware you plan to depend on is still maintained, since the project's own list of known middleware carries a TODO to verify and update it.

Frequently asked questions

What is Telegraf used for?

It is a library for developing Telegram bots with JavaScript or TypeScript. A Telegraf instance obtains updates and passes each one to your handlers, with full Telegram Bot API 7.1 support according to the README.

How do I install Telegraf?

Install the telegraf package with npm, yarn or pnpm, then create a bot instance with your BotFather token. The README gives npm install telegraf as the first option.

How does Telegraf work?

Telegraf creates one Context instance per incoming update and passes it to your middleware. Handlers registered with bot.command, bot.hears or bot.on run in order, and the Context carries the update, botInfo and a telegram client for API requests.

How do I stop a Telegraf bot?

The README's examples call bot.stop with the signal name, wired to process.once for SIGINT and SIGTERM. This is described there as enabling graceful stop.

How do I use Telegraf?

Create a Telegraf instance with your bot token, register handlers such as bot.start, bot.help, bot.hears or bot.on with a filter, and call bot.launch. The README's example shows all of these in one file.

Who owns Telegraf?

The package.json lists the author as The Telegraf Contributors, and the project is published from the telegraf organisation on GitHub under the MIT licence.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. telegraf/telegraf on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/telegraf-telegraf.svg)](https://hysenlabs.com/projects/telegraf-telegraf)