telegram

@twa-dev/sdk: How to Build Telegram Web Apps That Actually Work

@twa-dev/sdk makes building Telegram Web Apps dramatically easier. Here's what it does, how to set it up, and what to watch out for.

Grow your business on Telegram

CRM, Outreach & Lead Research. Get started with 1-week free trial.

Grow your business on Telegram

CRM, Outreach & Lead Research. Get started with 1-week free trial.

Grow your business on Telegram

CRM, Outreach & Lead Research. Get started with 1-week free trial.

If you've tried building a Telegram Web App (TWA) without any abstraction layer, you know the pain. Talking directly to window.Telegram.WebApp works — but it's verbose, inconsistent across platforms, and has zero type safety. That's exactly what @twa-dev/sdk fixes.

This article covers what the SDK actually does, how to install it, what its key features are, and where people run into problems. No fluff — just what you need to ship something.

What Is @twa-dev/sdk?

@twa-dev/sdk is an open-source TypeScript/JavaScript package that wraps the Telegram Web App JavaScript API. It's maintained by the community and lives on GitHub.

The raw Telegram Web App API is exposed as a global object injected into your webview by Telegram. It works, but it was designed for browser environments — not modern TypeScript frontends. @twa-dev/sdk gives you:

  • Full TypeScript typings (no more guessing what fields exist)

  • Reactive wrappers around Telegram events

  • Consistent behavior across iOS, Android, and Telegram Desktop

  • A cleaner developer experience with proper module imports

In short: you write less boilerplate and catch more bugs at compile time instead of at 2am when a user reports a crash.

Installing and Setting Up @twa-dev/sdk

Getting started is straightforward. Install the package via npm or yarn:

npm install @twa-dev/sdk
# or
yarn add @twa-dev/sdk
npm install @twa-dev/sdk
# or
yarn add @twa-dev/sdk
npm install @twa-dev/sdk
# or
yarn add @twa-dev/sdk

Then import it into your app. The SDK exports a default WebApp object that mirrors the Telegram Web App API — but with types and some extra quality-of-life improvements:

import WebApp from '@twa-dev/sdk';

WebApp.ready(); // Tell Telegram the app is loaded
console.log(WebApp.initDataUnsafe.user); // Typed user object
import WebApp from '@twa-dev/sdk';

WebApp.ready(); // Tell Telegram the app is loaded
console.log(WebApp.initDataUnsafe.user); // Typed user object
import WebApp from '@twa-dev/sdk';

WebApp.ready(); // Tell Telegram the app is loaded
console.log(WebApp.initDataUnsafe.user); // Typed user object

That's it for the basics. No configuration files, no setup ceremony. If you're using React, Vue, or Svelte — it drops right in.

One Thing to Watch Out For

The SDK is designed to run inside the Telegram WebView environment. If you try to run your app in a regular browser (e.g., during local development), window.Telegram.WebApp won't exist, and you'll get errors. The typical fix is mocking the object locally or using a Telegram Mini App testing environment.

Use WebApp.isExpanded, WebApp.platform, and environment checks to guard platform-specific logic during development.

Key Features You'll Actually Use

Main Button and Back Button

Telegram Web Apps have native UI elements — the Main Button (the big button at the bottom) and the Back Button (in the header). Managing these with raw API calls is clunky. With @twa-dev/sdk:

WebApp.MainButton.setText('Confirm Order');
WebApp.MainButton.show();
WebApp.MainButton.onClick(() => handleConfirm());

WebApp.BackButton.show();
WebApp.BackButton.onClick(() => router.back());
WebApp.MainButton.setText('Confirm Order');
WebApp.MainButton.show();
WebApp.MainButton.onClick(() => handleConfirm());

WebApp.BackButton.show();
WebApp.BackButton.onClick(() => router.back());
WebApp.MainButton.setText('Confirm Order');
WebApp.MainButton.show();
WebApp.MainButton.onClick(() => handleConfirm());

WebApp.BackButton.show();
WebApp.BackButton.onClick(() => router.back());

Clean, typed, and predictable. You'll use these constantly in any non-trivial mini app.

Init Data and User Authentication

When a user opens your TWA, Telegram injects initData — a string containing user info, chat context, and a hash you can verify server-side. The SDK parses this for you:

const user = WebApp.initDataUnsafe.user;
// { id: 123456789, first_name: 'Alex', username: 'alex_dev', ... }
const user = WebApp.initDataUnsafe.user;
// { id: 123456789, first_name: 'Alex', username: 'alex_dev', ... }
const user = WebApp.initDataUnsafe.user;
// { id: 123456789, first_name: 'Alex', username: 'alex_dev', ... }

Always validate initData on your server — never trust the client alone. The hash is signed with your bot token, so you can verify it with HMAC-SHA256. This is how you authenticate users without passwords or OAuth flows.

Haptic Feedback

Small touch, big UX difference. The SDK exposes WebApp.HapticFeedback with three methods:

  • impactOccurred('light' | 'medium' | 'heavy' | 'rigid' | 'soft')

  • notificationOccurred('error' | 'success' | 'warning')

  • selectionChanged()

Use haptics when users confirm actions, hit errors, or scroll through lists. It makes your app feel native — not like a wrapped website.

Theme and Color Variables

Telegram injects CSS variables for the user's current theme (light/dark, custom colors). The SDK gives you easy access via WebApp.themeParams, so you can build UI that looks native regardless of the user's Telegram theme settings.

@twa-dev/sdk vs. Raw Telegram Web App API: What's the Real Difference?

Honestly? For small projects, you can get by with the raw API. The global Telegram.WebApp object is well-documented and doesn't require any dependencies.

But the moment your project grows past a single file, the raw API becomes a liability:

  • No TypeScript types means constant any casts and runtime surprises

  • Event handling is manual and easy to leak (forgetting to remove listeners)

  • Cross-platform quirks (iOS vs. Android vs. Desktop) surface as production bugs, not compile errors

@twa-dev/sdk is the right default for any serious project. The dependency cost is minimal. The DX improvement is real.

Common Pitfalls When Building Telegram Web Apps

Even with a good SDK, people run into the same issues. Here's what to watch for:

  • Calling WebApp.ready() too late. Call it as early as possible — it tells Telegram your app has loaded and stops the loading spinner. Delay it and users see a blank screen longer than necessary.

  • Not handling viewport changes. The keyboard pops up, the viewport shrinks. If you're not listening to WebApp.onEvent('viewportChanged', ...), your layout will break on mobile.

  • Assuming initDataUnsafe is safe. The name says it all. Always verify the initData string server-side before trusting any user info.

  • Hardcoding colors instead of using theme variables. Your app will look broken in dark mode or for users with custom Telegram themes.

  • Ignoring WebApp.expand(). By default, the mini app opens in a partial view. Call WebApp.expand() if you want full-screen — most apps benefit from this.

Also worth reading: Telegram Mini App security practices — especially if your app handles any user data or payments.

When Telegram Web Apps Make Sense for Sales and CRM Workflows

Here's where this gets interesting from a business angle. Telegram Web Apps aren't just for games and utilities. They're increasingly being used to embed CRM interfaces, lead capture forms, onboarding flows, and dashboards directly inside Telegram chats.

Think about the friction of asking a sales prospect to open a separate browser tab, sign up, and fill out a form. Now compare that to a button inside a Telegram message that opens a mini app directly — pre-filled with their Telegram identity, no login required.

That's a fundamentally different conversion funnel. If you're building custom Telegram-based workflows on top of an existing CRM, the CRMChat API is worth looking at — it's designed specifically for building integrations between Telegram and sales pipelines, which pairs naturally with mini app front-ends.

For more on the broader Telegram Mini App API surface, this overview of the Telegram Mini App API covers what's available beyond just the SDK.

The Bottom Line

Use @twa-dev/sdk if you're building anything beyond a weekend prototype. It gives you types, cleaner event handling, and cross-platform consistency — all for zero real cost.

Your starting checklist:

  1. Install @twa-dev/sdk and swap out raw window.Telegram.WebApp calls

  2. Call WebApp.ready() as early as possible

  3. Call WebApp.expand() if you want full-screen

  4. Validate initData server-side — always

  5. Use theme variables so your UI doesn't look broken in dark mode

  6. Test on real devices (iOS and Android), not just the browser

That's the foundation. Build on top of it.

Continue Reading

The latest handpicked blog articles