Your First Deploy
This walkthrough takes you from an empty directory to a live Telegram Mini App. You will scaffold a project, test it locally, and deploy it to production.
Create and develop locally
Section titled “Create and develop locally”-
Scaffold the project. Run
tma initand select the Vite React template:Terminal window tma init my-first-app -
Enter the project directory.
Terminal window cd my-first-app -
Link the directory to a TMA.sh project.
Terminal window tma linkIf needed, choose + Create new project in the prompt.
-
Edit your app. Open
src/App.tsxand replace the contents with a simple Mini App that greets the user:import { useEffect, useState } from "react";function App() {const [name, setName] = useState("there");useEffect(() => {const webapp = window.Telegram?.WebApp;if (webapp) {webapp.ready();const user = webapp.initDataUnsafe?.user;if (user?.first_name) {setName(user.first_name);}}}, []);return (<main style={{ padding: "2rem", textAlign: "center" }}><h1>Hello, {name}!</h1><p>Your first Telegram Mini App is running.</p></main>);}export default App; -
Start the dev server. The
tma devcommand starts a local Vite dev server with hot reload:Terminal window tma devYou will see output like:
Local: http://localhost:5173 -
Test locally in the browser. Open
http://localhost:5173and verify hot module replacement works while you edit.
Deploy to production
Section titled “Deploy to production”Once you are happy with the app, deploy it to the world.
-
Initialize a Git repo and push to GitHub.
Terminal window git initgit add .git commit -m "init"git remote add origin https://github.com/your-username/my-first-app.gitgit push -u origin main -
Connect the repository. Open the TMA.sh dashboard, navigate to your project, and connect your GitHub repository. This installs a GitHub webhook that triggers deployments on pushes to your configured deploy branch (default:
main). -
Push a change to trigger a deploy. Any push to
mainkicks off an automatic deployment. Check status in the dashboard or viatma logs. -
Your app is live. Once the deployment finishes, your Mini App is available at:
https://my-first-app.tma.shIf a production bot is registered, its Web App URL is automatically updated to point at the production deployment.
What happens during a deploy
Section titled “What happens during a deploy”When you push to main, TMA.sh runs the following pipeline:
- GitHub webhook — TMA.sh receives the push event.
- Build container — a clean environment runs your project’s configured install and build commands (defaults to
npm installandnpm run buildfor newly created dashboard projects unless you change them). - Upload assets — the build output is uploaded to the global CDN.
- Update bot URL — if a production bot is registered, its Web App URL is pointed at the new deployment.
- Ready — your app is live and serving traffic.
If you have a server/api/index.ts file, TMA.sh also bundles and deploys your API routes to my-first-app--api.tma.sh.
Deployment statuses
Section titled “Deployment statuses”Each deployment moves through these stages:
| Status | Meaning |
|---|---|
| queued | Push received, waiting for a build slot. |
| building | Dependencies are being installed and the project is being built. |
| deploying | Build output is being uploaded to the CDN and bot URL is being updated. |
| ready | Deployment is live and serving traffic. |
| failed | Something went wrong. Check the build logs with tma logs. |
| cleaned | Deployment assets have been cleaned up (old deployments). |
| purged | Deployment has been permanently removed. |
Auto-deploy
Section titled “Auto-deploy”By default, every push to main triggers a deployment. You can toggle auto-deploy on or off in your project settings on the dashboard.
When auto-deploy is off, use tma deploy to deploy manually.
Next steps
Section titled “Next steps”Your Mini App is live. From here, you can:
- Add API routes to handle server-side logic.
- Set up authentication to identify Telegram users.
- Accept payments via TON or Telegram Stars.
- Use KV storage for simple data persistence.
- Configure a custom domain for your app.