Custom Discord Community Bot Development In Discord.js + TypeScript

Every serious community eventually outgrows MEE6, Carl-bot, and Dyno. The free tier hits a feature wall, the paid tier gates the things you actually want, and you are paying $11–$50 a month forever for a generic bot every other server runs. We build custom Discord bots in Discord.js v14 with TypeScript — the same stack we used for our own developer community, NexuDevs. 16 slash commands, 10 backend systems, 9 channel categories, full automod, ticket flow, news feeds, weekly roundups, leveling, showcase, polls, reminders, GitHub integration. Here is how we build them, what they cost, and why owning your bot beats renting one.

Back to Blog

Why Most Community Bots Cap Out At Tier-2 SaaS

If you have run a Discord server for more than six months, you know the rhythm: you start with MEE6 free, hit the welcome-message limit, upgrade to MEE6 Pro at $11.95/month, then realize you also need Carl-bot for reaction roles, then Dyno for moderation, then YAGPDB for custom commands. Three years and four bot subscriptions later, your server is paying $40–$80/month for a stack that still cannot do exactly what you want, because each bot is a generic platform serving thousands of servers.

The features you actually need are usually small — a custom /showcase command for your specific use case, branded embeds in your color palette, an XP system tied to your role hierarchy, a ticket flow that posts to your private staff channel and creates a GitHub issue automatically. None of those are hard to build. They are just impossible to configure inside a SaaS bot, because the SaaS bot has to keep its surface area generic.

A custom bot is a one-time engineering investment that delivers exactly the feature set your community needs, branded to your server's identity, hosted on infrastructure you control, with no rate limits and no monthly fees. You stop paying rent and start owning the asset.

16
slash commands shipped on the NexuDevs reference build
10
backend systems: welcome, XP, automod, tickets, news feeds, more
$0
monthly fees once deployed — just modest VPS hosting
100%
code & data ownership, full source delivered

The Stack: Discord.js v14, TypeScript, SQLite

Discord bots can be written in a dozen languages. We build on Node.js + Discord.js v14 in TypeScript, with better-sqlite3 for local persistence on small-to-mid communities and PostgreSQL for larger servers that need clustered deployments. This stack is battle-tested, has the largest ecosystem of any Discord library, and gives Discord's full intent and gateway API surface.

Node.js 20+ Discord.js v14 TypeScript 5 better-sqlite3 dotenv rss-parser tsx (dev) PM2 (production) Docker (optional) PostgreSQL (scale tier) REST API (slash command registration) Cron / setInterval (schedulers)

Why TypeScript? Because slash command builders, intent flags, embed structures, and interaction options all have strict shapes — and a typo in any of them silently fails at runtime. TypeScript catches those errors at build time. The reference NexuDevs codebase has zero any types in its public surface, and the build (tsc) is clean on every commit.

Slash Commands We Built On NexuDevs

Slash commands are the modern Discord interaction primitive — they show up natively in the message composer, support typed argument validation, and Discord will rate-limit and route them for you. Below is the complete command surface from the NexuDevs reference build, all written in TypeScript with full option validation and per-command permission checks.

/leaderboard & /rank

XP-based community leaderboard plus per-user rank cards with level, XP-to-next, and total messages. Pulls from the XP system in better-sqlite3.

/profile

Branded profile embed showing user roles, joined-on date, level, and links the user has registered (GitHub, portfolio, etc).

/showcase

Members post their projects to a curated showcase channel with title, description, link, tech-stack tags, and a community upvote reaction. Auto-archives weekly.

/news

Surfaces the latest items from a curated RSS feed list (Hacker News, dev.to, GitHub trending, etc.) directly inside Discord on demand.

/github

Lookup any public GitHub repo, user, or issue. Displays stars, recent commits, latest release, and links back to the canonical URL.

/poll

Creates branded polls with up to 10 options, configurable voting window, multi-select toggle, and live result tally inside the embed.

/remind

Personal reminders queued in the database with relative-time parsing ("in 2h", "tomorrow 9am", "next monday"). Bot DMs the reminder when due.

/roundup

Triggers an on-demand weekly roundup — top message, most active member, top showcase project, news highlights — posted to the home channel.

/stats

Server vitals: member count, online count, message volume last 24h/7d, top channels by activity. Useful for staff and growth tracking.

/ticket

Opens a private support thread with the user and staff role, with optional auto-claim, transcript on close, and webhook handoff to a help-desk tool.

/warn /mute /kick /ban

Full moderation suite. All actions logged to a private modlog channel, persisted in the database, with appeal-friendly reason fields.

Every command is registered via the REST deploy-commands.ts script, with full slash-command option validation: required vs. optional, integer ranges, choice enums, mention targets. Discord's interaction system handles the front-end — we never have to parse free-text arguments.

// src/commands/showcase.ts — one of 16 commands import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; export const data = new SlashCommandBuilder() .setName('showcase') .setDescription('Showcase a project to the community') .addStringOption(o => o.setName('title').setDescription('Project title').setRequired(true)) .addStringOption(o => o.setName('link').setDescription('GitHub or live URL').setRequired(true)) .addStringOption(o => o.setName('stack').setDescription('Tech stack tags')); export async function execute(i: ChatInputCommandInteraction) { // Build branded embed, post to showcase channel, // award XP, reaction-bookmark, persist to SQLite }

Backend Systems: The Invisible 70% Of A Real Bot

Slash commands are the visible surface. The systems running underneath are what separate a serious community bot from a weekend hack. The NexuDevs reference build ships with 10 distinct backend systems, each isolated as a single TypeScript module under src/systems/.

welcome.ts

Custom-branded welcome embed on member join, role assignment, intro channel ping, and DM with onboarding links. Every join logged for analytics.

xp.ts

Per-message XP gain with cooldown (no spam farming), level-up announcements, role-reward unlocks at threshold tiers, and full history retained.

automod.ts

Spam detection, link allowlist/blocklist, mass-mention guard, raid protection (rapid-join throttle), and configurable swear filter with per-server config.

tickets.ts

Private support thread orchestration: open, claim, transcript, auto-close after inactivity, and optional webhook to external helpdesk (Zendesk, Plain).

newsfeed.ts

Polls a list of RSS feeds on cron, deduplicates, and posts new items to a designated news channel with branded embed and source attribution.

githubFeed.ts

Watches a list of GitHub repos via webhooks or polling, posts new releases, issues, and PRs into Discord with rich embeds and direct links.

weeklyRoundup.ts

Sunday-evening cron writes a branded weekly summary: top posts, top contributors, new members, showcase highlights. Published to the home channel.

showcase.ts

Backs the /showcase command. Auto-archives older posts, sorts by upvote count, and rotates a "spotlight" pick to the home channel weekly.

modlog.ts

Centralized audit log: every warn/mute/kick/ban from the moderation commands persists with timestamp, reason, target, and acting moderator.

feedScheduler.ts

Master cron coordinator. Runs newsfeed every 30 min, weekly roundup Sunday 6pm, ticket auto-close hourly, and any other timed system the server needs.

Architecture note: Every system is a self-contained module that exports an init(client) function. src/index.ts is essentially a one-screen file that imports each system, calls init, and starts the gateway connection. Adding a new feature is a single new file under src/systems/ — no spaghetti, no cross-cutting changes.

Custom Bot vs. MEE6 vs. Carl-bot vs. Dyno

Here is how a custom-built community bot stacks up against the major SaaS players for a server that has actually outgrown the free tier.

Capability Custom Bot MEE6 / Carl-bot / Dyno
Branded embeds & colors Pixel-perfect to your palette Generic templated embeds
Custom commands & logic Anything — full TypeScript Limited to UI builder + macros
External integrations Any REST API, webhook, or DB Pre-set vendor list only
Database access SQLite or Postgres, you own it Vendor's hosted DB, no export
Per-server feature flags Granular — pay nothing extra Tier-locked behind upgrade
XP retention Forever — in your DB Often paywalled or rate-limited
Ongoing cost ~$5–$15/mo VPS only $11–$50/mo per bot, indefinitely
Code & data ownership 100% yours, full source Vendor's IP, vendor's terms

Deployment, Hosting & Operations

The bot needs to be online 24/7 with auto-restart, log rotation, and a clean way to ship updates. We deploy to your VPS or cloud account using PM2 for process management. PM2 keeps the bot alive, restarts it on crash, rotates logs, and lets you ship updates with a one-line pm2 reload.

# Production startup — from scripts shipped with the reference build $ npm install --production $ npm run build # tsc compile to dist/ $ npm run deploy-commands # register slash commands $ pm2 start dist/index.js --name nexudevs-bot $ pm2 save && pm2 startup # auto-start on reboot # Ship an update $ git pull && npm run build && pm2 reload nexudevs-bot

Deployment options scale to your size. A 1,000-member community can run on a $5/mo Hetzner box. A 50,000-member community gets PostgreSQL, Redis, and a horizontally-scaled gateway shard pool — same codebase, different deploy target. Either way you own the credentials end-to-end.

What We Can Build For Your Server

If you run a developer community, a SaaS user community, a creator Discord, an alumni network, or a private member server — a custom bot is a 4–8 week build that pays for itself within a year against the SaaS subscriptions it replaces. We start from the NexuDevs reference architecture (16 commands, 10 systems) and customize from there.

Community-Grade Bot

Welcome flows, XP, leaderboards, showcase, automod, tickets, polls, news feeds, weekly roundups. Branded to your server identity.

Integration Layer

Connect Discord to GitHub, GitLab, Linear, Trello, Notion, Stripe, Zapier, your CRM, your DB — anything with an API or webhook.

Notification Bot

Cron-driven feeds: cron jobs, server health, deploy events, monitoring alerts, daily standups — all delivered as branded embeds.

SaaS Product Bot

Member-only access tied to Stripe subscription status, automated role assignment, support ticket capture, deflection via FAQ search.

Course / Cohort Bot

Cohort progress tracking, automated weekly check-ins, peer accountability pairs, instructor Q&A queue, certificate issuance hooks.

Multi-Server Federation

Single bot serving multiple Discord servers with shared XP, cross-server announcements, federated moderation logs, and tenant isolation.

Frequently Asked Questions

How long does it take to build a custom Discord bot?
A starter bot — 5–8 commands, welcome flow, basic moderation — ships in 2–3 weeks. A community-grade bot like NexuDevs (16 commands, 10 systems, automod, tickets, news feeds, GitHub integration, weekly roundups) takes 6–10 weeks. We deliver in milestones so you can deploy each system as it lands instead of waiting for everything at once.
Do you handle Discord application setup, intents, and verification?
Yes. We walk through the Discord Developer Portal setup, configure the right gateway intents, scope the OAuth invite link, and (if your server is large enough) help with Discord's bot verification process for the privileged intents.
Can you migrate XP and roles from MEE6 or another bot?
Yes. MEE6 ships an XP export and most other bots have similar tools. We import the existing leaderboard data into the custom bot's SQLite/Postgres database so members keep their levels and your community does not lose history during the cutover.
What happens if Discord changes their API?
Discord.js v14 is actively maintained and tracks Discord's API changes. We ship the bot with a maintenance plan option — either a monthly retainer or a per-incident rate — so when Discord deprecates something or rolls out a new feature you want to adopt, the work is already scoped and we can ship the update fast.

Ready to retire MEE6 and own your community bot?

If your server is paying for two or three SaaS bots and still hitting feature ceilings — let us scope the custom build. Call or text Jacob at (320) 360-8285 or message DM HUNT through the contact form for a same-day reply.

Free Quote