Guide
Keep your bot token out of your code
A bot token is a password that never asks for two-factor authentication. Anyone who has it is your bot. Here is how to keep it out of your source, in Node.js, Bun and Python.
← All guides2 min readUpdated
Why it matters
Whoever holds your bot's token can log in as it and do anything its permissions allow, in every server it is in. Tokens leak in boring ways: a repository made public, a screenshot of the editor, a file pasted into a support server to ask for help.
Discord scans public GitHub repositories for bot tokens and resets any it finds, which protects your bot and also takes it offline until you notice. Telegram does not, so a leaked Telegram token stays usable until you revoke it.
The fix is to keep the token out of your code entirely. Your code reads it from an environment variable — a named value the operating system hands to your program — and the token lives somewhere that is never shared or committed.
Node.js and Bun
Read the token from process.env. On your own machine, put it in a file called .env next to your code. Bun loads .env by itself; Node.js 20.6 and later can with the --env-file flag; on older versions, the dotenv package does it.
.env
DISCORD_TOKEN=paste-your-token-here
index.js
// Only needed on Node.js without --env-file. Bun reads .env on its own.
require('dotenv').config();
client.login(process.env.DISCORD_TOKEN);Python
Read it from os.environ. The python-dotenv package loads a .env file into the environment first; install it and add it to requirements.txt.
main.py
import os from dotenv import load_dotenv # Does nothing if there is no .env, so the same code works on a host # that sets the variable itself. load_dotenv() bot.run(os.environ["DISCORD_TOKEN"])
Never commit the .env file
Add .env to .gitignore before your first commit, so git never picks it up. If other people work on the bot, commit a .env.example with the variable names and no values, so they know what to fill in.
Deleting a committed .env in a later commit does not remove it: it is still in the repository's history, readable by anyone who can see the repository. If a token has ever been committed, treat it as leaked and reset it.
.gitignore
.env node_modules/ __pycache__/
On a host
A host sets environment variables for your program itself, so the same process.env or os.environ line reads the value there too, with no .env file needed. On our hosting, set it in your server's settings in the panel, then restart the bot so it picks up the new value.
Your server is private to your account, so uploading a .env file alongside your code also works. The panel is still the better place: the token stays out of your files entirely, so it cannot end up in a zip you share or a screenshot of your file manager.
If a token leaks
Reset it at once. For Discord, open your application in the Developer Portal, go to Bot, and press Reset Token; the old one stops working immediately. For Telegram, send /revoke to @BotFather and choose the bot. Then update the environment variable wherever the bot runs and restart it.
Check what the bot did while the token was out — deleted channels, mass messages, bans. A token with Administrator in a large server can do serious damage quickly, which is one more reason to ask for only the permissions a bot needs.
FAQ
Questions
Is a client ID or application ID secret?
No. The client ID appears in every invite link. The token and the client secret are the secrets; keep both out of your code.
My token is "undefined" after moving it to .env.
The file was not loaded, or the name does not match. Check that .env sits in the folder the bot is started from, that dotenv or load_dotenv runs before the token is read, and that the variable name is spelt the same in both places.