discordx: decorators on top of discord.js, spread across twelve packages
🤖 Create a discord bot with TypeScript and Decorators!
At a glance
- What is it?
- discordx is a TypeScript framework that adds decorators to discord.js and ships as a monorepo covering dependency injection, project scaffolding, pagination and music playback. Its published tags stop at [email protected] in June 2024 while the repository was pushed on 2026-07-29, so the versioning gap is part of the adoption decision.
- Who is it for?
- Adopt discordx when you are writing a TypeScript Discord bot, already depend on discord.js, and want command handlers declared as decorated classes rather than registered imperatively, since the decorators are an extension layer and the underlying discord.js behaviour is unchanged.
- Can I use it commercially?
- Yes. Apache-2.0 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 86 days 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 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An extension layer over discord.js, not a rival client
The positioning is stated plainly in the README: discordx is an extension of discord.js, so the internal behaviour, its methods and its properties, is the same. What the library adds is the ability to use TypeScript decorators on top of that client, with the stated aim of simplifying code and improving readability.
That framing decides most of the evaluation. You are not choosing between discordx and another client, you are choosing whether to put a decorator layer over discord.js or to write your command handling directly against it. The underlying gateway, message and collection APIs remain discord.js, so anything you learn about discord.js still applies, and a bot written with discordx still depends on discord.js rather than replacing it.
The audience is therefore narrow and identifiable: TypeScript developers building Discord bots who want their commands, events and services declared as classes and methods with metadata attached rather than wired up by hand. The topic tags reinforce that reading, with bot, command, decorators, slash, slash-commands and discord-js all listed.
The documentation lives at discordx.js.org, with a tutorial series on dev.to, a FAQ page and a Discord community server, and the repository also holds an examples directory under the main discordx package.
Twelve packages, and most of them are optional
The repository is a monorepo with a packages/ directory and a pnpm workspace definition, and the README enumerates what is inside it. The core package is discordx itself. Around it sit create-discordx for generating a project from templates, @discordx/di for dependency injection with support for agnostic IOC, and @discordx/importer, described as an import solution for both ESM and CJS. @discordx/internal holds the internal methods used by discordx, and @discordx/utilities is a general utility package.
The remaining packages are about features rather than plumbing: @discordx/lava-player, a Lavalink player library written in TypeScript for Node.js, with @discordx/lava-queue as its queue system; @discordx/music, a music player using YTDL; @discordx/plugin-lava-player and @discordx/plugin-ytdl-player, two fully featured players; and @discordx/pagination for creating paginated messages.
That the music code exists in four separate packages, in two parallel implementations, is the most useful thing in this list for an adopter. Lavalink based playback and YTDL based playback are alternative approaches to the same problem, and picking the wrong one means carrying a dependency you will replace later.
A team building a moderation or utility bot can install discordx alone and ignore most of the list.
create-discordx removes the wiring work before you write a line
Scaffolding is a first class package here, not an afterthought in a template repository. create-discordx is described as a CLI tool for generating a discordx project using templates, which means the starting point for a new bot is a command rather than a hand assembled package.json, tsconfig and bot entry file.
That matters more than it sounds in a decorator based framework, because decorators imply a compiler configuration and a specific module system. A scaffold produced by the maintainers is the path of least resistance through those decisions, and it is also the path the documentation examples assume.
The repository's own workspace tooling shows how the maintainers expect the code to be developed, and it is a reasonable model for a contributor. The root package.json is a private package that orchestrates the workspace with turbo, and its scripts are short.
"scripts": {
"build": "turbo run build",
"build:typedoc": "turbo run build:typedoc",
"check": "biome check",
"fix": "biome check --write",
"prepare": "husky",
"prettier": "prettier --check .",
"test": "turbo run test"
},The declared package manager is pinned in the same file.
"packageManager": "[email protected]",So a contributor works in a pnpm workspace, builds and tests every package through turbo, formats with biome and prettier, and installs husky through a prepare script.
Dependency injection and the ESM versus CJS import problem
Two packages exist to solve problems that would otherwise sit inside your bot code. @discordx/di is described as a dependency injection service with support for agnostic IOC, meaning it can be wired to a container implementation rather than insisting on one. @discordx/importer is an import solution for both ESM and CJS.
The importer exists because of the module system split in the Node ecosystem. A bot that imports command classes needs those modules loaded so their decorated methods register themselves with the framework. Doing that by hand means writing loader code that knows about your file layout, and getting it wrong usually shows up as commands that silently do not appear.
The DI package serves the same kind of problem from the other direction. A bot with a database, an HTTP client and a permissions service tends to accumulate constructors passing dependencies down, and a container removes that plumbing. Saying the container is agnostic keeps it from becoming the framework's opinion about how your services are built.
Neither package is required to use discordx, and neither is documented in the README beyond a single line each. The detailed documentation is on the discordx.js.org site, which is where the README sends you.
Music, pagination and utilities as separate install decisions
The feature packages are where dependency weight shows up, so they are worth choosing one at a time.
The Lavalink path is @discordx/lava-player plus @discordx/lava-queue, described as a Lavalink player library written in TypeScript for Node.js, with a queue system alongside it, and @discordx/plugin-lava-player which presents the same approach as a fully featured Discord music player. The YTDL path is @discordx/music, a music player library using YTDL, and @discordx/plugin-ytdl-player as its fully featured equivalent.
The two routes have different operational shapes. A Lavalink based player is described as leveraging Lavalink, which is a separate audio service, so that setup involves standing up and managing a service alongside the bot. The YTDL based route keeps playback in the Node process and downloads media through YTDL, which means the bot host does the network work and the media handling.
@discordx/pagination is the exception that carries no such operational weight: it is a library for creating pagination messages in Discord bots, useful for any bot that lists anything. @discordx/utilities is the same kind of package, generic helpers that enhance discordx functionality.
Note that the most recently released tagged package in the list is @discordx/plugin-ytdl-player at version 2.3.0, which dates the YTDL line of development separately from the core.
Tag dates are older than the commits
The release history is thin and stops well before the last commit. The listed releases are [email protected] from 2024-06-29, [email protected] from 2024-06-24 and @discordx/[email protected] from 2024-06-20. The repository itself was last pushed on 2026-07-29 and is not archived.
So the code is moving and the tags are not. A project on npm at version 11.12.0 is running code from mid 2024, and anything merged into the repository after that date exists only on the branch until a release is cut. The root package.json does carry the tooling for that: @changesets/cli and @changesets/changelog-github are development dependencies, and a .changeset/ directory sits at the repository root, which is the standard setup for versioning many packages from one commit.
The licensing is Apache-2.0, with LICENSE.txt at the root. The root package is private and its publishConfig sets access to restricted, so it is the individual packages under packages/ that carry the publishable artifacts.
A SECURITY.md file and a .husky/ directory with commit hooks complete the picture of a project with a release process in place, even if the recent tag history does not show it being used.
Decorators versus writing the registration yourself
The alternative to discordx is not another framework, it is discord.js with a hand written command handler, and the difference shows up in exactly one place: how a command becomes registered.
With discord.js alone you attach a listener to an interaction event, check the command name against a collection, parse options and dispatch. The work is not large, and it is entirely explicit. The cost is that you write and maintain that dispatch code, and that every new command has to be registered in the place where your collection is defined.
With discordx the command is a decorated method on a decorated class, and the metadata the framework needs is attached at build time by the TypeScript compiler. Registration becomes a side effect of loading the module. That is a cleaner shape for a bot with many commands and a shared service layer, particularly when the DI package is used to supply those services, since the class can then declare what it needs instead of receiving it from a dispatcher.
The cost of that approach is compiler configuration and a build step, plus an extra framework between you and discord.js for anything you need to debug. For a small utility bot, plain discord.js with a hundred lines of dispatch code is often the smaller commitment. For a bot that grows into a dozen command groups sharing services, the decorator route stops being a preference and becomes the maintainable option.
Editorial conclusion
Adopt discordx when you are writing a TypeScript Discord bot, already depend on discord.js, and want command handlers declared as decorated classes rather than registered imperatively, since the decorators are an extension layer and the underlying discord.js behaviour is unchanged. Do not adopt it for a JavaScript project, for a bot that must not depend on discord.js, or as a way to pin a known good version, because the newest tags are [email protected] from 2024-06-29 and the plugin-ytdl-player tag from 2024-06-20. Verify first by scaffolding a project with create-discordx and running it against your own application id, then confirm on the discordx.js.org documentation site which packages you actually need from the monorepo.
Frequently asked questions
What is discordx and does it replace discord.js?
discordx is a TypeScript framework that adds decorators to discord.js. The README states it is an extension of discord.js, so the internal behaviour, methods and properties are the same, and it adds decorator based command and event declarations on top.
How do I start a new discordx project?
Use the create-discordx package, which the README describes as a CLI tool for generating a discordx project using templates. The documentation site at discordx.js.org hosts the tutorials, the FAQ and further examples.
What are the latest discordx releases?
The listed releases are [email protected] from 2024-06-29, [email protected] from 2024-06-24 and @discordx/[email protected] from 2024-06-20. The repository was last pushed on 2026-07-29 and is not archived, and the licence is Apache-2.0.
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/discordx-ts-discordx)Was this useful?