node-telegram-bot-api
A runtime-agnostic, fully-typed TypeScript client for the Telegram Bot API, with middleware routing, sessions, and zero dependencies.
Repository Health
Technical Analysis
node-telegram-bot-api v2 is a from-scratch rewrite of the long-running Node.js Telegram bot client, built as a web-standard TypeScript SDK that runs unmodified on Node.js, Bun, Deno, Cloudflare Workers, and Vercel Edge Functions. At its center is a Bot composition root with koa-style middleware (use/on/command/hears) dispatching through a single handleUpdate path shared by long-polling and webhooks, alongside an Api client that mirrors the Telegram Bot API 1:1, one method per endpoint.
The library ships builders for inline/reply keyboards, rich-text entities, media groups, and sticker sets; a pluggable session layer with in-memory, file, SQLite, Redis, and SQL-backed stores; streaming file uploads that keep memory flat regardless of size; and adapters for Express, Next.js App Router, Cloudflare Workers, and a self-hosted Node webhook server. The transport layer handles retries, exponential backoff, 429 flood-wait handling, and optional proactive rate limiting, surfacing failures through a structured error hierarchy instead of untyped exceptions.
What You Get
- A
Botclass withuse/on/command/hearsmiddleware routing and a singlehandleUpdatedispatch path shared by polling and webhooks - An
Apiclient that mirrors the Telegram Bot API method-for-method, each call taking one typed params object - Builders for inline/reply keyboards, rich-text entities, media groups, and sticker sets that serialize to plain Telegram payload shapes
- A pluggable session middleware with in-memory, file, SQLite, Redis, and SQL store adapters, plus a reply-tracking layer built on top of it
- Streaming file uploads (
InputFile,fromPath) that keep memory flat on large uploads and replay safely on retry - Webhook adapters for Express, Next.js App Router, Cloudflare Workers/Bun/Deno, and a self-hosted Node HTTP server
- A resilient transport with automatic retries, exponential backoff, 429
retry_afterhandling, and optional proactive per-chat rate limiting - A structured error hierarchy (
NetworkError,TimeoutError,ParseError,TelegramApiError) instead of untyped throws
Common Use Cases
- Building a command-driven Telegram bot (support bot, notification bot, admin utility) with
bot.command()routing - Running a bot on Cloudflare Workers or Vercel Edge Functions via the web-standard
webhookCallback - Building multi-step conversational flows with the session middleware and reply-tracking to know which prompt a reply answers
- Calling the Telegram Bot API directly (e.g. from a backend job) via the standalone
Apiclient without running a bot loop - Sending media-rich messages - photos, documents, media groups, and inline/reply keyboards - built with the included builders
Under The Hood
Architecture
The library is layered as types (generated, exhaustively-typed Update/Bot-API schemas) under core (the Node-free, edge-safe engine: Bot, Api, Transport, Context, compose) under node/bun (runtime-specific adapters - file-based sessions, webhook servers, SQLite/Redis stores). Bot is the composition root: it holds one Api, an ordered middleware array, and an error boundary, dispatching every update through a single handleUpdate path that both startPolling() and webhookCallback funnel into, so polling and webhook delivery can never diverge in behavior. Transport is deliberately the only module that touches fetch, injectable via options.fetch for testing, and owns retry/backoff/429 handling behind a typed request<R>() call. Registration-order middleware composition (compose.ts) is a small, dependency-free koa-compose reimplementation, and on/command/hears are themselves middleware wrappers pushed onto the same chain rather than a separate routing system, so a session or auth middleware registered via use() wraps everything downstream uniformly.
Tech Stack
Written entirely in TypeScript with zero runtime dependencies, built with zshy into dual ESM/CJS output plus a dedicated Bun-targeted build (tsconfig.bun.json), and linted/formatted with Biome. Tests run under Bun’s native test runner and, in parallel, under node:test via tsx, so the suite is verified on two runtimes in CI. A custom scripts/check-core-imports.mjs enforces that src/core never imports a node:* module, and scripts/check-edge-bundle.mjs verifies the core bundle stays edge-runtime-safe - both run as CI gates, not just conventions. Webhook adapters target Express, Next.js App Router, and native Node http, while store adapters cover SQLite, Redis, and generic SQL for session persistence.
Code Quality
The test suite spans roughly twenty files and thousands of lines covering routing, transport retries, encoding, sessions, webhooks, and rate limiting, with a dedicated test/e2e suite that can run against the live Telegram API. Error handling is fully typed: every failure mode (network, timeout, parse, Telegram API error) is a distinct TelegramBotError subclass with structured fields (errorCode, retryAfter) rather than string-matched messages, and an isTransientError helper centralizes retry classification. CI runs tsc --noEmit separately for src, test, and examples, alongside the core-isolation and edge-bundle checks, so a change that leaks a Node dependency into core or breaks the public examples fails the build.
What Makes It Unique
Most Telegram bot libraries in this space target Node.js only; this one treats Node as just one of several first-class runtimes (Bun, Deno, Cloudflare Workers, Vercel Edge), unifying them behind a single web-standard (Request) => Promise<Response> webhook contract and an injectable-fetch transport. The per-update dispatch tables in Context (mapping every update variant to its chat/from resolver) are typed so that adding a new Telegram update kind is a compile error until every table has a matching row, giving exhaustiveness guarantees uncommon in hand-rolled SDKs. The opt-in reply-tracking layer, built strictly on top of the session middleware rather than in-memory promises, lets multi-step conversations survive process restarts and work correctly under one-invocation-per-update serverless execution.
Used by 2 apps in this directory
AnythingLLM
Developer Tools · Automation · AI Assistants
The all-in-one AI platform for private document chat, no-code agents, and local LLMs with zero setup friction.
Postiz
Social Media · Automation
The agentic social media scheduler — AI-powered content creation, 33-platform posting, and team workflows, all self-hosted.