packages
yaebal is a pnpm monorepo. three foundation packages, a stack of first-party plugins, plus scaling
and tooling — all under the @yaebal/* npm scope, published as ESM with full TypeScript
types.
# install everything (workspace bootstrap)
pnpm install
# or add individual packages to your project
pnpm add @yaebal/core @yaebal/session @yaebal/keyboardfoundation
| package | description |
|---|---|
yaebal | batteries-included entry — core + auto-generated contexts + common plugins, one import |
@yaebal/core | Bot, Composer, context, filter queries, media helpers — the engine everything else builds on |
@yaebal/types | full Telegram Bot API types, code-generated from our own parser of the live docs; single source of truth for all interfaces |
@yaebal/contexts | per-update context classes with auto-generated shortcut methods (ctx.reply, ctx.sendPhoto, …) |
plugins
each plugin is a typed composer extension. installing one enriches the context type; its dependencies are checked at compile time. see the plugins overview for a quick orientation.
| package | description |
|---|---|
@yaebal/fmt | html`` / md`` tagged templates → entities, with auto-escaped interpolation |
@yaebal/rich | sendRichMessage / sendRichMessageDraft: block builder, streaming drafts, full read-side coverage |
@yaebal/filters | composable, type-narrowing update filters: and / or / not, commands, deep links, media, async |
@yaebal/guards | reusable bot.guard() predicates: isAdmin, isPrivate, isGroup, hasMembership, hasPermission |
@yaebal/conversation | await-style multi-step dialogs — coroutine by default, durable replay engine opt-in |
@yaebal/again | awaited retry on structured retry_after / transient 5xx errors |
@yaebal/session | typed sessions: dirty-checked saves, lazy mode, multi-session, ttl fields, migrations |
@yaebal/sklad | zero-dep storage adapters: memory (ttl/lru), redis, sqlite, cloudflare kv, json file |
@yaebal/cache | ctx.cache.get/set/wrap — ttl memoization, stale-while-revalidate, sliding expiry, negative caching, prefix invalidation, typed key catalog |
@yaebal/feature-flags | ctx.flags.isEnabled(key)/getVariant(key) — typed boolean & A/B/n flags, telegram-native targeting, global overrides, guard/whenFlag, admin commands, LaunchDarkly/GrowthBook/env adapters |
@yaebal/keyboard | fluent inline & reply keyboard builders |
@yaebal/callback-data | typed callback_data pack / unpack |
@yaebal/payments | typed invoice builder (stars / external providers), pre-checkout & successful-payment hooks, star subscriptions |
@yaebal/mini-app | telegram Mini Apps server protocol — HMAC + Ed25519 (third-party) initData validation, typed parser & test signer, Authorization: tma header helper, answerWebAppQuery, WebAppInfo/deep-link url generator |
@yaebal/link-preview | fluent builder for link_preview_options |
@yaebal/inline-results | typed builders for every InlineQueryResult / InputMessageContent variant |
@yaebal/auto-answer | auto-clears the callback-query loading spinner, no manual answerCallbackQuery call |
@yaebal/hydrate | hydrated api results — the returned Message gains editText/delete/pin/forward/copy/react, no manual chat_id or message_id |
@yaebal/typing | ctx.typing(fn) keeps the "is typing…" indicator alive for an async call, no manual sendChatAction |
@yaebal/ephemeral | ctx.replyEphemeral() — answer in a group so only the asker sees it, typed edit/delete handle, private-chat fallback |
@yaebal/ai | ctx.ai.replyStream() — llm answers streamed via telegram drafts / throttled edits, model adapters (openai-compatible, anthropic, ai sdk, custom), conversation memory, per-user limits — plus the ai dev tooling (mcp server + agent installer) |
@yaebal/morda | dialogs engine + jsx/hooks (react-for-telegram) |
@yaebal/i18n | typed ctx.t (keys + params), Intl plurals, language_code detection |
@yaebal/scenes | durable wizards: typed state, ask() validation, navigation, sub-scenes, ttl |
@yaebal/state-machine | declarative finite-state machines: typed events, guarded transitions, onEnter/onLeave hooks |
@yaebal/onboarding | declarative first-run tutorials with inline controls |
@yaebal/prompt | ask a question, await the next message as the answer |
@yaebal/router | typed file-based routing — define*() routes, nested guards, watchRoutes hot-reload |
@yaebal/toml | declarative toml routes with a typescript handler registry |
@yaebal/throttle | priority outbound scheduler with global/private/group buckets |
@yaebal/files | inspect, link, stream and download Telegram files |
@yaebal/file-id | parse and re-serialize file_id / file_unique_id strings |
@yaebal/ratelimiter | drop updates from users who send too many requests |
@yaebal/broadcast | typed broadcast jobs with storage, retry, progress and controls |
@yaebal/cron | typed cron jobs: timezones, retries, catch-up, distributed locks, and a chat-native admin surface |
@yaebal/web | webhooks on any runtime — edge, node/bun/deno servers, serverless, and fetch frameworks; adapters, sequentialize, dedupe, lifecycle |
@yaebal/panel | framework-agnostic operator panel with media, keyboards and events |
@yaebal/analytics | ctx.track(event, properties) with pluggable sinks: posthog, plausible, sqlite, clickhouse |
@yaebal/audit-log | correlated, redacted-by-default audit logging — sinks, formatters, filters, sampling, chatSink, auditAdmin |
@yaebal/media-group | collect albums into one handler call or ctx.mediaGroup |
@yaebal/split | long text as multiple messages — entities survive the split |
@yaebal/commands | one registry for handlers + the / command menu — localized, scoped, diff-synced |
@yaebal/pagination | paginated lists over any source — lazy fetch, item buttons, typed payload |
@yaebal/media-cache | upload once, reuse the file_id — self-heals when telegram rejects it |
@yaebal/preview | render telegram-style chats to a standalone SVG string — reply quotes, reactions, link previews, custom themes (experimental) |
scaling & tooling
| package | description |
|---|---|
@yaebal/runner | concurrent update processing with per-chat sequentialization |
@yaebal/workers | worker_threads pool to offload CPU-heavy tasks from handlers |
@yaebal/test | testing utilities — mock api with real hooks & error simulation, update factories for every update kind, webhook helpers |
create-yaebal | project scaffolder — pnpm create yaebal |
all packages require Node.js ≥ 20 and are ESM-only (
"type": "module"). use import type for type-only imports — verbatimModuleSyntax is enabled
across the workspace.