TitanBot: a modular all-in-one Discord bot with PostgreSQL persistence
A powerful, all-in-one Discord assistant built for every server.
At a glance
- What is it?
- TitanBot bundles moderation, economy, leveling, tickets, giveaways and Lavalink music into one Discord.js v14 bot. It installs through Docker Compose or npm, keeps state in PostgreSQL, and ships its own migration and backup scripts.
- Who is it for?
- Adopt TitanBot if you run a community server and want moderation, economy, leveling, tickets and music behind one bot process with a PostgreSQL database you control. Do not adopt it if you need a bot that runs without a database, or if you expect the music feature to work without Lavalink nodes you are willing to maintain.
- 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?
- Yes. The repository last received commits 73 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- codebymitch/TitanBot9,588 ★ · +1,371
| Repository | 2026-09-22 | 2026-11-14 |
|---|---|---|
| codebymitch/TitanBot | 8.2k | 9.6k |
1,371 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
What TitanBot replaces, and for whom
Most Discord communities end up running several bots: one for moderation, one for leveling, one for tickets, one for music. Each brings its own database, its own permission model and its own downtime. TitanBot's pitch is consolidation. The feature table in the README covers moderation (mass ban and kick, user notes, case management), an economy with shop, inventory, gambling and a pay command, leveling with XP tracking and level roles, giveaways with multiple winners and rerolls, reaction roles, a ticket system with claim, priority, limits and transcripts, server stat counters, birthdays with timezone handling, welcome messages with auto roles, and music.
The target user is a server operator who is comfortable running a Node.js process and a PostgreSQL instance, or who is willing to run two containers through Docker Compose. That is a different audience from the people who click a hosted bot invite link and never see a config file. TitanBot asks for a Discord application, a bot token, a client ID and a guild ID before it will start, and the README points non-coders at a video tutorial rather than pretending the setup is trivial.
The package description calls it a "Modular Ultimate Community Bot by Touchpoint Support", and the repository layout supports that claim: commands, events and database access live under src/, with separate scripts/ for migrations and backups.
How the data flow works: Discord.js, PostgreSQL and Lavalink
TitanBot is an ESM Node.js application. package.json sets "type": "module" and points the start script at src/app.js, so the entry point is not index.js even though that file exists at the repository root. Dependencies are conventional for this kind of bot: discord.js v14 for the gateway and REST layer, pg for PostgreSQL, express for an HTTP surface, node-cron for scheduled work, winston with winston-daily-rotate-file for logging, zod for validation, and riffy for Lavalink.
State lives in PostgreSQL. The .env.example exposes a full pool configuration rather than a single connection string: POSTGRES_MAX_CONNECTIONS defaults to 20, POSTGRES_MIN_CONNECTIONS to 2, with separate connection and idle timeouts and a retry policy governed by POSTGRES_RETRIES, POSTGRES_BACKOFF_BASE and POSTGRES_BACKOFF_MULTIPLIER. That level of tuning suggests the bot holds a long-lived pool rather than opening a connection per command. Migrations are tracked in a table named by POSTGRES_MIGRATION_TABLE (schema_migrations by default), and AUTO_MIGRATE=true is the default in .env.example and in the Compose file.
Music is delegated. The bot does not decode audio itself; it talks to Lavalink v4 through Riffy. By default it reads a list of public v4 SSL nodes from lavalink/nodes.json, sourced according to the README from lavalink.darrennathanael.com. If you would rather not depend on public nodes, the Compose file defines a lavalink service behind the local-lavalink profile, and the bot then reads LAVALINK_HOST, LAVALINK_PORT, LAVALINK_PASSWORD and LAVALINK_SECURE from the environment instead of the nodes file.
There is also an HTTP surface. The bot listens on PORT 3000 with WEB_HOST 0.0.0.0 and answers a health check at /health, which the Compose healthcheck calls with Node's fetch.
Installing TitanBot with Docker Compose
The README marks Docker deployment as recommended, and it is the shortest path because the Compose file wires the bot and PostgreSQL together. Start by cloning and copying the environment template:
git clone https://github.com/codebymitch/TitanBot.git
cd TitanBot
cp .env.example .envOpen .env and set at minimum DISCORD_TOKEN, CLIENT_ID and GUILD_ID. The Compose file also reads POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB from that file, with defaults of titanbot, password and titanbot. Then build and start:
docker compose up -d --build
docker compose ps
curl http://localhost:3000/healthThe README states this starts the bot and PostgreSQL together, with POSTGRES_SSL=false and AUTO_MIGRATE=true set for the bundled database. If the health check returns a non-OK response, check the container logs before assuming the token is wrong. The image is also published to GitHub Container Registry on every push to main, so `docker pull ghcr.io/codebymitch/titanbot:main` is an alternative to building locally.
Manual installation and the first commands you run
The manual path needs Node.js 20.10.0 or higher, which package.json enforces through the engines field, plus a PostgreSQL server. The README notes a memory storage fallback exists, but it recommends PostgreSQL, and everything about migrations and backups assumes a real database.
git clone https://github.com/codebymitch/TitanBot.git
cd TitanBot
npm install
cp .env.example .envEdit .env with the Discord values and the PostgreSQL block. The README's example uses POSTGRES_URL=postgresql://postgres:yourpassword@localhost:5432/titanbot along with the discrete POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD variables. Once the database is reachable, the migration scripts are the first thing to run:
npm run migrate:status
npm run migrate:check
npm run migratemigrate:status reports what the migration table contains, migrate:check verifies without applying, and migrate applies. Then start the bot with `npm start`, which runs node src/app.js. The README recommends NODE_ENV=production and LOG_LEVEL=warn for a clean production console. For music, use `/play <song>` from a voice channel, or `/join` to connect without playing; prefix shortcuts include join, np, leave, pause, resume, skip, stop and volume <0-100>.
Where TitanBot is the wrong tool
The database requirement is the first boundary. TitanBot is not a bot you invite and forget. It wants a PostgreSQL instance, a migration table, a connection pool and a backup routine. If your server is small enough that losing leveling data would not matter, you are paying operational cost for persistence you do not need.
Music is the second. The default configuration points at public Lavalink v4 SSL nodes from a third-party list. Public nodes are shared infrastructure: you do not control their uptime, their capacity or their rate limits. Self-hosting Lavalink removes that dependency but adds a service to run, and the README is explicit that you must remove or rename lavalink/nodes.json so the bot falls back to the LAVALINK_* environment variables. Skip that step and your self-hosted node is ignored.
The third boundary is scale of configuration. The .env.example is long. Pool sizes, retry backoff, migration table names, schema version labels, backup retention and CORS origin are all exposed. That is good for operators and bad for anyone who wanted a two-line config. The README's own production note covers only NODE_ENV, LOG_LEVEL and port retries, which understates how many knobs exist.
TitanBot compared with a hosted all-in-one bot
The obvious alternative is a hosted bot that already provides moderation, leveling and music, where you authorize it and configure everything through slash commands. The difference is ownership of state. With a hosted bot, your leveling records, notes and ticket transcripts live in someone else's database, and your only export path is whatever that service offers. With TitanBot, they live in a PostgreSQL database you run, and the repository ships scripts/backup.js and scripts/restore.js behind npm run backup:db and npm run restore:db, plus a restore drill at npm run backup:drill.
That backup tooling is the strongest argument for the self-hosted route, and it is also the honest measure of the cost. You are not just choosing a bot; you are choosing to be the person who restores it. The restore drill script is the closest thing to a safety net and you should understand it before you need it.
A narrower alternative is to keep a hosted bot for music and run TitanBot only for the persistent features. Lavalink is the component most likely to break without warning, since by default it relies on public nodes.
Maintenance, upgrades and the MIT licence
TitanBot is released under the MIT licence, which permits commercial and private use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive licence, and it means you can fork the bot and keep your changes private. It offers no warranty, so the operational risk of a broken migration or a leaked token sits with you. This is a description of the licence text, not legal advice.
The release history shows v1.1.1 in May 2026, v2.0.0 in June 2026 and v3.0.0 in July 2026, with the last push to main on 2026-09-03. Note the version mismatch: package.json declares version 2.1.0 while the latest tagged release is v3.0.0, so do not assume the package version tells you which release you are running. Check the tag you cloned.
Upgrade cost is dominated by migrations. AUTO_MIGRATE=true means the bot applies migrations on start, which is convenient in development and risky in production if you have not taken a backup first. The scripts give you the tools: npm run backup:db writes to BACKUP_DIR, which defaults to ./backups, with BACKUP_RETENTION_DAYS set to 14. A defensible upgrade sequence is backup, migrate:check, migrate, then start. Treat the backup as the rollback.
Editorial conclusion
Adopt TitanBot if you run a community server and want moderation, economy, leveling, tickets and music behind one bot process with a PostgreSQL database you control. Do not adopt it if you need a bot that runs without a database, or if you expect the music feature to work without Lavalink nodes you are willing to maintain. Before you commit, verify three things in your own environment: that the Discord application has the intents the README requires, that `curl http://localhost:3000/health` returns a healthy response after `docker compose up -d --build`, and that the migration scripts run cleanly against a copy of your production database.
Frequently asked questions
What is TitanBot?
TitanBot is a Discord bot built on Discord.js v14 and PostgreSQL that bundles moderation, economy, leveling, tickets, giveaways, reaction roles, server stats, birthdays, welcome messages and Lavalink music into one application. The repository describes it as a modular community bot and ships Docker Compose and manual npm installation paths.
How do I install TitanBot?
Clone the repository, copy .env.example to .env, set DISCORD_TOKEN, CLIENT_ID and GUILD_ID at minimum, then run docker compose up -d --build. A manual path also exists: npm install, configure the PostgreSQL variables, run npm run migrate, then npm start.
Does TitanBot need PostgreSQL?
The README recommends PostgreSQL and the migration, backup and restore scripts all assume a real database, though it also mentions a memory storage fallback. Docker Compose starts a postgres:15-alpine container alongside the bot with AUTO_MIGRATE=true.
Why is TitanBot music not working?
Music depends on Lavalink v4 nodes reached through Riffy. By default the bot loads public SSL nodes from lavalink/nodes.json, and if you switch to the self-hosted lavalink profile you must remove or rename that file so the bot falls back to the LAVALINK_HOST, LAVALINK_PORT, LAVALINK_PASSWORD and LAVALINK_SECURE environment variables.
What Node.js version does TitanBot require?
package.json sets the engines field to node >=20.10.0, and the README lists Node.js 20.10.0 or higher as a prerequisite for manual installation. The Dockerfile builds on node:20-alpine.
Official sources
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.
[](https://hysenlabs.com/projects/codebymitch-titanbot)Star history chart for your README
[](https://hysenlabs.com/projects/codebymitch-titanbot)Was this useful?