Self-hosted service
KevinNovak/Discord-Bot-TypeScript-Template avatar
KevinNovak/Discord-Bot-TypeScript-Template

Discord Bot TypeScript Template: a discord.js starting point

Discord bot - A discord.js bot template written with TypeScript.

643 stars130 forksTypeScriptMIT

At a glance

What is it?
The Discord Bot TypeScript Template gives you a working discord.js bot with command structure, rate limits, cooldowns, a welcome message, sharding, clustering, PM2 and Docker support, and ESM throughout. It is aimed at developers who would rather not write the initial setup again.
Who is it for?
The template fits a developer starting a Discord bot who wants command registration, cooldowns, a welcome message and a deployment story in place before writing a single feature, since all of that is already here.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the template already does for you

The stated purpose is to give developers a starting point for new Discord bots so that much of the initial setup can be avoided and they can focus on meaningful bot features, with the workflow being to copy the repository, follow the setup instructions and have a working bot with many boilerplate features already included. The built-in list covers a basic command structure, rate limits and command cooldowns, a welcome message when the bot joins a server, the server count shown in the bot status, posting the server count to popular bot list websites, and support for multiple languages. The last of those two is worth pausing on, since posting your server count to third party listing sites is a growth strategy that not every bot author wants, and it is a line in the configuration you would want to turn off. The developer friendly list adds TypeScript, the discord.js framework, a built-in debugging setup for VSCode, ESM for future compatibility with packages, and support for running with PM2 and with Docker.

Sharding and clustering, the two growth paths

The template's most distinctive feature is that it already handles the two ways a Discord bot outgrows one process, and the README links each to its own documentation. Sharding is supported, and the README notes it is required when your bot is in 2500 or more servers, which is Discord's own threshold for when a single process cannot handle the gateway traffic. Clustering is supported through a separate repository, the Discord-Bot-TypeScript-Template-Master-Api, and it allows you to run your bot on multiple machines. The distinction matters and is easy to miss. Sharding splits one bot across several processes on one machine, each owning a slice of the guilds. Clustering runs several complete instances, usually on separate hosts, with an API in front coordinating them, which is what you need when a single box is not enough. The start scripts in the package.json cover the first case directly, with a manager mode that spawns multiple bot shards, and the second is a separate project.

The setup, step by step

Setup is five steps. First you copy the example config files: navigate to the `config` folder, copy all files ending in `.example.json` and remove the `.example` from the copied file names, so `config.example.json` becomes `config.json`. Second you obtain a bot token, which means creating a new bot in the Discord Developer Portal, with a linked walkthrough of the process, and the README asks you to make sure you end up with a bot token. Third you modify the config file, opening `config/config.json` and setting `client.id` to your bot's user ID and `client.token` to the token. Fourth you install packages with `npm install`. Fifth you register the commands, because slash commands have to be registered before they can be used, with `npm run commands:register`.

Slash command registration is a separate step

The command registration step is the one that trips people up, and the README is unusually clear about it. You need to run `npm run commands:register` any time you change a command name or structure, or add or remove commands, and the reason given is so Discord knows what your commands look like. The same step may take up to an hour for the changes to appear, which is a property of how Discord distributes command definitions to clients rather than of the bot. The package.json shows the full family of command scripts, and every one of them follows the same pattern of building first and then running a Node entry point with source maps enabled. There is a `commands:view` script to inspect what is registered, and `commands:rename`, `commands:delete` and `commands:clear` for the lifecycle operations. The pattern is a good one to copy, since the build step is always bundled with the command, so you never register a stale build.

The start scripts and the process managers

There are three ways to run the bot, and they differ in who supervises the processes. Normal mode is `npm start`, which starts a single instance of the bot. Manager mode is `npm run start:manager`, which starts a shard manager that spawns multiple bot shards. And PM2 mode is `npm run start:pm2`, which is similar to manager mode but uses PM2 to manage the processes. The package.json shows how these compose, with the start script delegating to `start:bot`, the manager script building and then running `dist/start-manager.js`, and the PM2 script building and then calling `pm2 start process.json`. The repository has a `process.json` at the top level, which is the PM2 process definition, and the `clean` script is notable for what it preserves, using `git clean -xdf` with an exclude for the config directory, so a reset of the working tree does not wipe your credentials.

The Docker image and the Node version gap

The Dockerfile is the weakest part of the template as it stands, and the reason is a version mismatch you can see in two places. The image is built FROM node:16, while the package.json requires Node 18.0.0 or newer through its engines field, and the package is an ES module with exports pointing at `dist/start-bot.js` and `dist/start-manager.js`. The build steps themselves are conventional, as the image file shows:

dockerfile
FROM node:16

# Create app directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install packages
RUN npm install

# Copy the app code
COPY . .

# Build the project
RUN npm run build

# Expose ports
EXPOSE 3001

# Run the application
CMD [ "node", "dist/start-manager.js" ]

The port exposure is worth understanding too, since the manager runs a coordinator that other shards report to, and the master API project linked for clustering is the piece that would serve on a port like that. The mismatch is not fatal, because a newer base image would work, but shipping a Dockerfile whose base image is behind the declared engine floor is the kind of detail that makes a template less useful than it looks.

The repository as a code base

The top level of the repository shows a full project rather than a snippet. There is a `src/` directory for the source, a `config/` directory for the configuration, a `lang/` directory for the localisation files that back the multiple language support, a `misc/` directory, a `tests/` directory, a `Dockerfile`, a `.dockerignore`, an `eslint.config.mjs`, a `tsconfig.json` and a separate `tsconfig.test.json`, a `vitest.config.ts`, a `package-lock.json`, a `.vscode/` directory for the debugging setup, a `.gitbook.yaml` and a `docs` arrangement, plus a `CLAUDE.md` and a `LEGAL.md`. The package.json records the project as `my-bot` at version 1.0.0, marked private, with the author Kevin Novak, and the test script is `vitest run` with a coverage variant and a watch mode, so the template ships with a test runner configured rather than leaving you to pick one. There is also a LICENSE and a LEGAL.md, and the licence is MIT.

Where this is the wrong choice

The limits are mostly about what the template assumes. First, it is a bot with opinions, not a skeleton. A welcome message, a server count in the status, posting to listing sites and a rate limit system are all sensible for a public bot and all wrong for a private one, and the work is stripping them out rather than adding them. Second, the slash command model is baked in, so if you want prefix commands or interaction buttons with a custom design, you are working against the structure rather than with it. Third, the Dockerfile age issue described earlier, which is the first thing you will hit if you deploy with Docker. Fourth, the sharding and clustering story is two projects, so the scaling path is not a single switch, and the clustering half lives in a separate repository that you have to evaluate on its own. Fifth, there is no release history on the repository, no tags, so a template you copy is a copy of whatever is on master on the day you copy it, and there is no changelog to tell you what changed between versions. The bot list in the README, with bots built on the template, is a reasonable proxy for how much real use it has seen.

Editorial conclusion

The template fits a developer starting a Discord bot who wants command registration, cooldowns, a welcome message and a deployment story in place before writing a single feature, since all of that is already here. It is the wrong choice if you want a minimal starting point, because the feature list is a working bot rather than a skeleton, and the wrong choice if you have to run the Docker image as it ships, since the Dockerfile is built on a Node 16 base while the package requires Node 18 or newer. Before you start, copy the example config files, register your slash commands after every change to them, and read the sharding and clustering notes. The last push was on 2026-04-19, the repository publishes no GitHub releases, and the licence is MIT.

Frequently asked questions

How do I set up the Discord Bot TypeScript Template?

Copy the config files ending in `.example.json` in the `config` folder and remove the `.example` from the names, create a bot in the Discord Developer Portal to get a token, set `client.id` and `client.token` in `config/config.json`, run `npm install`, and then run `npm run commands:register` so the slash commands are registered with Discord.

How do I run the bot in multiple shards?

Use `npm run start:manager`, which starts a shard manager that spawns multiple bot shards. The README notes that sharding is required when your bot is in 2500 or more servers. A PM2 mode, `npm run start:pm2`, is similar but uses PM2 to manage the processes.

What does the Discord Bot TypeScript Template include out of the box?

A basic command structure, rate limits and command cooldowns, a welcome message when joining a server, the server count shown in the bot status, posting the server count to popular bot list websites, and support for multiple languages. On the developer side it adds TypeScript, discord.js, a VSCode debugging setup, ESM, and PM2 and Docker support.

Official sources

  1. Issues
  2. KevinNovak/Discord-Bot-TypeScript-Template on GitHub
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kevinnovak-discord-bot-typescript-template.svg)](https://hysenlabs.com/projects/kevinnovak-discord-bot-typescript-template)

Was this useful?