Best Tech Stack for Building a Discord Bot as a Solo Developer
The ideal tech stack for solo developers building a Discord bot in 2026.
I've built and maintained several Discord bots over the past few years. The one that taught me the most was a moderation bot I built for a gaming community. It started as a 200-line script and grew into something much bigger. Every poor architecture decision I made in the first version haunted me for months. The stack I recommend now is the result of those lessons.
Discord bots are fun because the feedback loop is immediate. Run a command, see the result. But they're also systems that need to run 24/7, handle concurrent users, and scale to multiple servers. Picking the right tools from the start makes the difference between a bot that runs smoothly and one that constantly crashes at 3 AM.
The Recommended Stack
| Layer | Tool | Current Version | Why |
|---|---|---|---|
| Runtime | Node.js | 24.16.0 LTS (Krypton) | Best Discord library ecosystem |
| Language | TypeScript | 6.0.3 | Slash commands need type safety |
| Library | Discord.js | 14.26.4 | Most mature, best maintained |
| Database | SQLite (small) or PostgreSQL (growing) | SQLite 3.53.1 / Postgres 18.4 | SQLite is zero-config, Postgres scales |
| ORM | Prisma or Drizzle | Prisma 7.8.0 / Drizzle 0.45.2 | Type-safe queries, migrations |
| Hosting | Railway or Fly.io | n/a (hosted) | Always-on, affordable, easy deploys |
| Task Queue | BullMQ (if needed) | 5.77.6 | Scheduled tasks, background jobs |
| Logging | Pino | 10.3.1 | Fast structured logging |
All versions above were checked on the npm and vendor registries on 2026-05-30 and are listed in the Sources section at the end. Pin them in your package.json rather than tracking the latest, since Discord.js in particular ships breaking minor releases.
Why This Stack Works for Solo Developers
Discord bots need to be online all the time. Unlike a web app where a few seconds of downtime is barely noticeable, a Discord bot going offline means commands fail, events are missed, and users immediately notice. This makes hosting choice and reliability crucial.
The Node.js and Discord.js combination is the default for a reason. Discord.js has the largest community, the best documentation, and handles the WebSocket connection to Discord's gateway reliably. It carries roughly 26,700 stars on GitHub and pulls about 683,000 downloads a week from npm, which is the kind of momentum that means your weird edge-case error already has a Stack Overflow answer. I've tried Python with discord.py (solid, but the async pattern is less intuitive if you come from web development), and even Go with discordgo (fast but the library is more low-level). For solo developers who already know JavaScript, Discord.js is the clear winner.
Run it on the current Node.js LTS line, which is 24.16.0 (codename Krypton) as of this writing. Discord.js 14.26.4 declares a minimum engine of Node 18, so the LTS gives you a comfortable margin and the security backports you want on a process that runs unattended around the clock.
TypeScript isn't optional in my opinion. Discord's slash command system involves complex option types, permission flags, and interaction responses. TypeScript catches mismatches at compile time that would otherwise crash your bot at runtime. A user triggers a command, your bot crashes because you passed a string where a number was expected, and nobody's around to restart it. TypeScript prevents that class of bug entirely.
Library: Discord.js
Discord.js v14 is the current stable line, sitting at 14.26.4 on npm at the time of writing. It's excellent. The builders pattern for creating slash commands, embeds, and components is clean and type-safe. Here's what I like about it.
The command handler pattern is well-established. Create a commands/ directory, put each command in its own file with a data property (the slash command definition) and an execute function, and load them dynamically on startup. Every serious Discord.js bot follows this pattern, and there are countless tutorials and examples to reference.
The event system is straightforward. Listen for messageCreate, interactionCreate, guildMemberAdd, and dozens of other events. The typing support means you get autocomplete for event data, which is a huge time saver.
One thing that tripped me up initially was the Gateway Intents system. Discord requires you to explicitly declare which events your bot needs access to. If you don't request the GuildMembers intent, you won't receive member join/leave events, and your bot will silently not work. Always check which intents your features require and enable them both in code and in the Discord Developer Portal.
Database: Start with SQLite
Here's an opinion that might surprise you. Use SQLite for your bot's database until you have a concrete reason not to. SQLite runs in-process, requires zero configuration, has no separate server to manage, and handles thousands of reads per second. The current stable release is 3.53.1, shipped on 2026-05-05, and it remains one of the most widely deployed databases on the planet. For a Discord bot storing server configurations, user preferences, or game state, SQLite is more than enough.
I used PostgreSQL from day one on my first bot because "real applications use real databases." It added deployment complexity (now I needed a database server), increased hosting costs, and the connection pooling overhead was totally unnecessary for my data volume. When I rebuilt the bot with SQLite, everything got simpler.
The migration path is clean too. Start with SQLite via Prisma, and when you actually hit a limit (concurrent write contention from multiple shards, or you need full-text search), switch to PostgreSQL by changing one line in your Prisma schema and running a data migration. Prisma abstracts the database engine.
When to use PostgreSQL from the start. If your bot runs on 1000+ servers, handles high-frequency events (like message tracking), or needs complex queries with joins across large datasets. In those cases, the connection pooling and concurrent write handling of Postgres justify the complexity. The current major line is PostgreSQL 18, with 18.4 released on 2026-05-14, so that is the version to target on a new deployment.
ORM: Prisma vs Drizzle
Both ORMs in the table are type-safe, actively maintained, and battle-tested. The data below was pulled from npm and GitHub on 2026-05-30.
| ORM | Current Version | GitHub Stars | npm Downloads (last week) | Best For |
|---|---|---|---|---|
| Prisma | 7.8.0 | ~46,000 | ~11.6 million | Schema-first workflow, generated client, easy migrations |
| Drizzle | 0.45.2 (drizzle-orm) | ~34,600 | ~9.7 million | SQL-like queries, lighter runtime, edge-friendly |
For a solo developer, Prisma's schema file and migration tooling make the SQLite-first then Postgres-later path I described above almost mechanical. Drizzle is the pick if you want queries that read like the SQL you already know and a thinner runtime footprint. Either is a defensible choice in 2026.
Hosting: Railway or Fly.io
Discord bots need a persistent WebSocket connection. This rules out serverless platforms like Vercel or Netlify Functions. Your bot needs to be a long-running process.
Railway is my first choice for solo developers. Deploy by connecting your GitHub repo, set your environment variables, and Railway keeps your bot running. New accounts get a one-time $5 trial credit with no credit card required, and the Hobby plan is $5 per month with included usage, aimed squarely at solo developers and side projects. That is enough to keep a small bot online 24/7. Deploys happen automatically on git push. (Check the current Railway pricing page before you commit, since usage-credit terms change.)
Fly.io is the alternative if you want more control. It runs your bot in containers closer to your users (though for Discord bots, latency matters less than for web apps). Fly is pay-as-you-go with no traditional free tier for new accounts anymore. The smallest always-on machine, a shared-cpu-1x with 256MB of RAM, runs about $2.02 per month in most regions, and stopped machines only bill for storage. That makes a tiny single-process bot genuinely cheap to keep online.
For larger bots (100+ servers), consider a VPS from Hetzner with PM2 for process management. The entry CX22 plan (2 vCPU, 4GB RAM, 40GB disk) is €4.49 per month after the April 2026 price adjustment, which is still excellent value for an always-on machine. PM2 (currently 7.0.1 on npm) auto-restarts your bot on crashes, manages logs, and can run your bot in cluster mode if needed. The tradeoff is that you manage the server yourself.
Hosting at a Glance
| Option | Model | Entry Cost | Notes |
|---|---|---|---|
| Railway | Subscription | $5/month Hobby (plus one-time $5 trial credit) | Easiest git-push deploys |
| Fly.io | Pay-as-you-go | ~$2.02/month for a 256MB always-on VM | No new-account free tier; cheap at small scale |
| Hetzner CX22 | VPS subscription | €4.49/month (2 vCPU, 4GB RAM) | Most control, you manage the box |
Prices checked on 2026-05-30; see Sources.
What I'd Skip
Microservice architecture. Your bot doesn't need a separate service for commands, events, and the database layer. One process handles everything until you're running a very large bot. I've seen developers split a 500-line bot into three "microservices" for no reason. Keep it simple.
Docker for development. Use Docker for production deployment if your hosting requires it, but develop locally with tsx watch (TypeScript execute with file watching). tsx is at 4.22.3 on npm and runs on Node 18 or newer. The hot-reload cycle is faster than rebuilding containers.
Complex caching layers. Redis caching for a Discord bot with 50 servers is unnecessary overhead. Discord.js already caches guilds, channels, and members in memory. Use that cache. Add Redis only when you're sharding across multiple processes and need shared state. Note that BullMQ, the task-queue pick in the stack table (5.77.6 on npm, around 5.6 million downloads a week), is itself a Redis-backed queue, so adding scheduled background jobs and adding Redis are the same decision. Hold both until you actually need them.
Sharding before you need it. Discord documents that each shard supports a maximum of 2,500 guilds, and apps in 2,500 or more guilds must enable sharding. Until you're close to that number, a single process handles everything fine. Premature sharding adds significant complexity to your database queries, caching, and command handling.
Web frameworks. Your bot doesn't need Express or Fastify unless you're building a web dashboard alongside it. The Discord gateway handles all communication. If you need a health check endpoint, a five-line HTTP server is enough.
Getting Started
Here's my first-day setup for a new Discord bot.
Create the project. Initialize a TypeScript project with
npm init -y, installdiscord.jsandtsx, set up your tsconfig, and create a basicsrc/index.tsthat connects to Discord's gateway.Set up the command handler. Create
src/commands/and add aping.tscommand. Register it with Discord's API using the REST module. Run the bot and test/pingin your test server.Add your database. Install Prisma, create your schema with the models your bot needs (GuildConfig, User, etc.), and generate the client. Wire it into your command handler.
Implement your core feature. Whatever your bot actually does, build it now. Get it working end to end in your test server.
Add structured logging. Install Pino (10.3.1 on npm, around 32 million downloads a week, the de facto fast JSON logger for Node) and log every command invocation and error. When your bot misbehaves at 3 AM, structured logs are the difference between a five-minute fix and an evening of guessing.
Deploy to Railway. Connect your repo, add the
DISCORD_TOKENenvironment variable, and push. Your bot goes online in about 90 seconds.
The best Discord bot stack is the one that stays out of your way while giving you the tools to build reliable features. This combination does exactly that. Start with the basics, ship your bot, and add complexity only when the number of servers or features demands it.
Sources
All figures above were checked on 2026-05-30.
- Node.js release index (latest LTS, version data)
- TypeScript on npm (version, weekly downloads)
- Discord.js on npm (14.26.4, Node engine requirement)
- Discord.js downloads (npm download counts API)
- Discord.js homepage and docs
- discordjs/discord.js on GitHub (star count)
- Discord developer docs, Gateway and sharding (2,500-guild threshold)
- SQLite home (3.53.1 release, 2026-05-05)
- PostgreSQL home (18.4, released 2026-05-14)
- Prisma on npm (7.8.0, weekly downloads)
- prisma/prisma on GitHub (star count)
- drizzle-orm on npm (0.45.2, weekly downloads)
- drizzle-team/drizzle-orm on GitHub (star count)
- BullMQ on npm (5.77.6, weekly downloads)
- Pino on npm (10.3.1, weekly downloads)
- tsx on npm (4.22.3, Node engine requirement)
- PM2 on npm (7.0.1)
- Railway pricing ($5 Hobby plan, $5 trial credit)
- Fly.io pricing (pay-as-you-go, ~$2.02/month for a 256MB VM)
- Hetzner Cloud (CX22 plan)
- Hetzner April 2026 price adjustment (CX22 now €4.49/month)
Like this? You'll like what I'm building too.
Two ways to support and get more of this work.
HEARTH
A privacy-first Life OS for your desktop. Journal, tasks, and notes that stay on your machine. Coming soon, direct download from this site.
Read moreMY TOOLKITS
Receipts-first toolkits for shipping after hours, building Claude agents, publishing on Amazon, and more. The exact methods I used, not theory.
Browse on WhopRelated Articles
AI Wrapper Stack Guide for Solo Developers
Complete guide to the AI wrapper stack - when to use it, setup, pros/cons, and alternatives.
Best Tech Stack for Building an AI Wrapper as a Solo Developer
The ideal tech stack for solo developers building an AI wrapper in 2026.
Best Tech Stack for an Analytics Dashboard as a Solo Developer
The best tech stack for building an analytics dashboard as a solo developer - frameworks, databases, hosting, and tools.