Skip to content

Environment Variables

Environment variables let you store secrets and configuration outside your codebase. They are encrypted at rest, decrypted at deploy time, and injected into your API routes as environment variables.

Terminal window
# Set a variable
tma env set DATABASE_URL=postgres://...
# Set another variable
tma env set ANALYTICS_KEY=ak_123
# List all variables
tma env list
# Remove a variable
tma env remove DATABASE_URL
# Pull variable names to a local .env.local file (values are redacted)
tma env pull

The CLI sets variables for the production environment. Environment scoping beyond production (preview, development) is managed through the dashboard.

Navigate to your project’s Settings > Environment Variables page. Add, edit, or remove variables from the web interface. Changes take effect on the next deployment.

Variables can be scoped to specific environments:

ScopeApplied to
ProductionProduction deployments (tma deploy)
PreviewPreview deployments (pull request branches)
DevelopmentLocal development (tma dev)

If a variable is set without a scope, it applies to all environments. Scoped variables override unscoped ones.

Environment scoping is managed through the dashboard at Settings > Environment Variables, where you can set different values for each environment. The CLI always targets the production environment.

Environment variables are available on the c.env object in your Hono API routes:

import { Hono } from 'hono';
type Env = {
Bindings: {
DATABASE_URL: string;
STRIPE_SECRET_KEY: string;
RESEND_API_KEY: string;
};
};
const app = new Hono<Env>();
app.post('/api/send-email', async (c) => {
const res = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
Authorization: `Bearer ${c.env.RESEND_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
from: 'noreply@myapp.tma.sh',
to: 'user@example.com',
subject: 'Hello',
text: 'Welcome to the app!',
}),
});
return c.json({ sent: res.ok });
});
export default app;

During tma dev, environment variables scoped to development are loaded automatically. You can also use a .env file in your project root for local overrides:

Terminal window
# .env (git-ignored by default)
DATABASE_URL=postgres://localhost:5432/myapp
STRIPE_SECRET_KEY=sk_test_...

The CLI loads .env values as a fallback when development-scoped variables are not set in the dashboard.

VariablePurpose
DATABASE_URLExternal database connection string
BOT_TOKENTelegram bot token
STRIPE_SECRET_KEYPayment processor credentials
RESEND_API_KEYEmail service API key
SENTRY_DSNError tracking
  • Variables are encrypted at rest and only decrypted during deployment.
  • They are never included in your static SPA bundle — only API routes have access.
  • Variables are not logged in build output or deployment logs.
  • Use the dashboard or CLI to rotate secrets without redeploying code — trigger a redeploy to pick up the new value.
  • Add .env to your .gitignore to prevent accidentally committing local secrets.