Ship a Telegram Mini App in 48 hours
A practical, end-to-end walkthrough — from BotFather to deploy — for shipping your first Telegram Mini App with auth, payments, and a real distribution plan.
Mini Apps are the closest thing the mobile web has to an App Store moment. They are HTML5 apps that run inside Telegram with native chrome, deep auth into the user’s identity, and a payments rail that takes minutes — not weeks — to wire up.
This guide takes you from zero to a deployed, paying-customers-ready Mini App in two days.
What is a Telegram Mini App?
A Mini App is a web page that Telegram embeds inside its own chrome. Your code is plain HTML/JS — React, Vue, vanilla, anything that runs in a browser. Telegram injects a JavaScript bridge (window.Telegram.WebApp) that gives you:
- Identity: a signed payload (
initData) you verify server-side to know who the user is. - Theme: the user’s current Telegram theme tokens, so your UI matches dark/light.
- Native UI primitives:
MainButton,BackButton, haptics, scanner, share link. - Payments: invoice flow that charges in Stars (digital goods) or fiat (physical).
The official surface is the Bot API, which exposes Mini Apps via web_app buttons. The full spec lives at core.telegram.org core.telegram.org/bots/webapps ↗ .
Prerequisites
- A Telegram account (a real one, not a virtual number).
- A laptop with Node 20+ (or Bun 1.1+).
- A domain or a free subdomain on Cloudflare/Vercel/Fly. Mini Apps must be served over HTTPS.
- 30 minutes for setup, then ~10 hours of actual coding spread across 2 days.
Create your bot with BotFather
Open Telegram, search @BotFather, send /newbot. Pick a display name and a _bot-suffixed username. Save the HTTP API token it gives you — you’ll need it server-side.
Then attach a Mini App:
/newapp → choose your bot
Title: Telegram Bible Demo
Description: Build on Telegram, fast.
Photo: upload 640×360 PNG
GIF: optional
Web App URL: https://your-app.example.com
Short name: demoYour Mini App is now reachable at t.me/your_bot/demo and via inline keyboard buttons.
Bootstrap the frontend
Use Vite + React (or your stack of choice). Install the Telegram SDK:
npm create vite@latest mini-app -- --template react-ts
cd mini-app
npm install @telegram-apps/sdk-reactIn main.tsx, initialize the bridge:
import { init, miniApp, viewport } from "@telegram-apps/sdk-react";
init();
miniApp.mount();
viewport.mount();
miniApp.ready();Calling miniApp.ready() tells Telegram your app has finished loading — Telegram hides its own loader and reveals your UI.
Authenticate the user, properly
Telegram passes a signed initData string to your Mini App. Never trust it client-side. Send it to your backend and verify the HMAC.
// server/auth.ts
import crypto from "node:crypto";
export function verifyInitData(initData: string, botToken: string): boolean {
const params = new URLSearchParams(initData);
const hash = params.get("hash")!;
params.delete("hash");
const dataCheck = [...params.entries()]
.sort(([a], [b]) => a.localeCompare(b))
.map(([k, v]) => `${k}=${v}`)
.join("\n");
const secret = crypto
.createHmac("sha256", "WebAppData")
.update(botToken)
.digest();
const computed = crypto
.createHmac("sha256", secret)
.update(dataCheck)
.digest("hex");
return computed === hash;
}Once verified, parse initData.user — that’s your trusted user object: { id, first_name, username, language_code }. Mint your own session JWT from it.
Charge with Stars in two API calls
Stars are Telegram’s in-app currency for digital goods. They are perfect for: unlocking premium features, tipping, paid templates, AI credits.
On your backend, create an invoice link via the Bot API:
const res = await fetch(`https://api.telegram.org/bot${TOKEN}/createInvoiceLink`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "Pro plan",
description: "Unlock the full guide library",
payload: `user_${userId}_pro_2026_04`,
currency: "XTR", // Stars
prices: [{ label: "Pro", amount: 250 }], // 250 Stars
}),
});
const { result: invoiceUrl } = await res.json();Hand invoiceUrl to the client and call:
import { openInvoice } from "@telegram-apps/sdk-react";
const status = await openInvoice(invoiceUrl);
// "paid" | "cancelled" | "failed" | "pending"Then handle pre_checkout_query and successful_payment updates server-side to grant entitlement.
Deploy and distribute
Push your frontend to Cloudflare Pages or Vercel — both give you HTTPS for free. Update the URL in BotFather. That’s it for hosting.
For distribution:
- Direct link:
t.me/your_bot/demoworks in any browser, opens Telegram if installed. - Start parameter:
t.me/your_bot/demo?startapp=ref_alex— read it ininitData.start_paramto do referral tracking. - Inline mode: users can
@your_botin any chat to share your app. - Channels: drop a message with a Mini App button in your channel.
- Stories: link Mini Apps from Telegram Stories — surprisingly high CTR.
Common gotchas
initDataempty in browser dev tools — that’s expected. Telegram only injects it inside the Telegram client. Use a tunnel, not localhost.- Theme flicker — read
themeParamsonce on mount and apply via CSS variables. Subscribe tothemeChangedfor runtime switches. - Viewport jump on iOS — call
viewport.expand()early; some keyboards otherwise compress your app. - Stars refunds — fully manual. Plan a
/refundadmin command from day one.
Next steps
- Add Cloud Storage (
window.Telegram.WebApp.CloudStorage) for cross-device persistence without your own DB. - Add a referral leaderboard using Stars-paid badges.
- Submit to the Telegram App Center once live (currently invite-only — apply via @BotSupport).
You shipped. Now grow.
Read next
Mini App monetization patterns that work (and 5 that don't)
A taxonomy of every Mini App monetization pattern in production today, with conversion rates, ARPU expectations, and the patterns to avoid.
Withdraw Stars without losing 30% to fees
A practical guide to converting Telegram Stars into bankable USD with minimum spread loss — every route, real fees, and the timing tactics that compound across a year.
Bot payments, end to end
A no-shortcut guide to accepting payments through a Telegram bot — Stars for digital, fiat for physical, refunds, webhooks, and the gotchas nobody documents.