Library / SDK
Rapptz/discord.py avatar
Rapptz/discord.py

discord.py: An Async Python Wrapper for the Discord API

An API wrapper for Discord written in Python.

16,187 stars3,916 forksPythonMIT

At a glance

What is it?
discord.py gives Python developers an async client and a command framework for Discord bots, installed from PyPI with an optional voice extra. The last push to the repository was on 2026-09-07.
Who is it for?
Adopt discord.py if you are writing a Python bot that needs async message handling, a command framework and documented slash command support, and you can accept that PyNaCl plus davey are only pulled in through the voice extra. Do not adopt it if you need a non-Python runtime or a client library for a protocol other than the Discord API.
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 23 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

What discord.py solves for Python bot authors

The README describes discord.py as an API wrapper for Discord written in Python, built around async and await. That framing matters: the library does not run a bot for you, and it does not host anything. It sits between your process and the Discord API, and its job is to turn raw gateway events and HTTP endpoints into Python objects you can call methods on. If you are writing a Python bot that reacts to messages, commands or interactions, this is the layer you would otherwise write yourself.

The audience is narrow and identifiable. You need to be comfortable with asyncio, because the entry point is client.run('token') and every handler is a coroutine. You need a bot token from Discord. You need at least Python 3.8, which pyproject.toml states as requires-python. The classifiers list Python 3.8 through 3.12, so the supported range is explicit rather than open-ended.

The project also ships a command framework under discord.ext.commands, which is a separate layer on top of the raw client. The README shows both styles side by side: a plain discord.Client subclass with an on_message handler, and a commands.Bot with a @bot.command() decorator. Choosing between them is the first real decision a new user makes, and the README does not argue for either.

How the client, intents and command layer fit together

The mechanism visible in the README is a client object that you configure with intents, then run. Intents are declared before construction: intents = discord.Intents.default() followed by intents.message_content = True. That second line is not optional decoration. Without it the bot will not receive message content, so the on_message example would never see the string 'ping'.

The command framework reuses the same configuration. In the bot example, commands.Bot takes a command_prefix and the same intents object, and commands are registered by decorating async functions. The prefix is a literal string, so '>' in the example means messages beginning with that character are parsed as commands.

Rate limit handling is claimed in the key features list, and aiohttp is the only runtime dependency in requirements.txt, pinned as aiohttp>=3.7.4,<4. That tells you the HTTP side is delegated to aiohttp rather than hand-rolled. There is also a conditional dependency, audioop-lts, marked for python_version>='3.13', which suggests the voice path needs a replacement for the standard library audioop module on newer interpreters. The README itself does not explain that line.

The repository layout shows where the depth is: a discord/ package, a docs/ directory, a tests/ directory, and an examples/ directory with files such as basic_bot.py, background_task.py, reaction_roles.py, and subdirectories for app_commands, modals and views. Slash commands live under the app_commands examples rather than the top-level ones.

Installing discord.py and running a first bot

The README requires Python 3.8 or higher and recommends a virtual environment, noting that on Linux the system Python is externally managed and restricts which packages you can install. Install the library without voice support with pip.

bash
python3 -m pip install -U discord.py

On Windows the README gives py -3 -m pip install -U discord.py instead. Voice support is a separate extra, which pulls in PyNaCl and davey according to pyproject.toml.

bash
python3 -m pip install -U "discord.py[voice]"

The README adds that installing voice support on Linux requires libffi-dev and python-dev (for example python3.8-dev for Python 3.8) from your package manager before running that command. If you want the development version, the README clones the repository and installs it locally.

bash
git clone https://github.com/Rapptz/discord.py
cd discord.py
python3 -m pip install -U .[voice]

A first working bot is the command example from the README. Save it, replace the token, and run it. The bot should print nothing on startup beyond the library's own logging, and typing >ping in a channel it can read should produce pong.

python
import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='>', intents=intents)

@bot.command()
async def ping(ctx):
    await ctx.send('pong')

bot.run('token')

If nothing responds, the message content intent is the first thing to check, since the README sets it explicitly in every example.

Where discord.py is the wrong choice

The clearest boundary is language. This is a Python library, and the README's examples are Python. If your service is written in another language, nothing here helps you, and the wrapper's design decisions (async and await, decorators, intents as an object) are Python-specific.

The second boundary is scope. The README describes an API wrapper, not a bot platform. There is no scheduler, no database, no dashboard, no deployment tooling in the repository layout. You supply the process, the token storage and the host. The examples directory contains patterns such as background_task.py and background_task_asyncio.py, but those are illustrations, not a runtime.

The third is version support. requires-python is >=3.8 and the classifiers stop at 3.12. If you are pinned to an older interpreter, the package metadata rules you out.

The fourth is voice. Voice support is an optional extra with a native dependency chain on Linux. Teams that only need text commands pay nothing for it, but teams that need voice inherit libffi-dev and python-dev as build prerequisites, plus PyNaCl and davey. The README does not document rollback or a fallback path if that install fails; it only states the prerequisite packages.

discord.py compared with Pycord

Pycord is the fork that comes up most often when people compare Python Discord libraries, and the difference is largely one of governance and release cadence rather than API shape. Both wrap the same Discord API, both expose an async client, and both offer a command extension with slash command support. A bot written against one is not a drop-in for the other, but the concepts map closely enough that porting is a matter of renaming imports and adjusting decorators.

What the README and repository files support is narrower than the comparison people usually want. The README lists rate limit handling and speed and memory optimisation as key features, and pyproject.toml carries Development Status :: 5 - Production/Stable with an MIT licence. Those are the concrete claims available. The README does not compare itself to Pycord, does not name it, and does not document migration between the two. Anyone choosing between them should read both projects' documentation rather than rely on this page for the difference, because the deciding factors (release timing, maintainer responsiveness, feature parity on newer Discord endpoints) are not recorded in the files reviewed here.

Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-09-07. That is recent enough to treat the codebase as moving, but there is no release list in the repository metadata, so there is no way to say how often versions ship or what changed between them. The version string is derived at build time from discord/__init__.py, and setup.py appends a commit count and short hash when the version ends in a, b or rc. That means a development install can carry a different version string than the published one, which is worth knowing when you file a bug report.

Upgrade cost is mostly ordinary pip work. The runtime dependency is aiohttp, constrained to >=3.7.4,<4, so a major aiohttp release would require a change in this project before you could move. The docs extra in pyproject.toml pins Sphinx at 4.4.0 and a set of sphinxcontrib packages, with comments noting that they should be bumped when migrating to a newer Sphinx version. That is a maintenance burden for contributors, not for users.

The licence is MIT, declared in pyproject.toml as license = { file = "LICENSE" } and in the classifiers. MIT is permissive, so redistribution and modification are allowed provided the licence text travels with the code. This is a description of the licence identifier, not legal advice; read the LICENSE file and your own organisation's policy before shipping.

Editorial conclusion

Adopt discord.py if you are writing a Python bot that needs async message handling, a command framework and documented slash command support, and you can accept that PyNaCl plus davey are only pulled in through the voice extra. Do not adopt it if you need a non-Python runtime or a client library for a protocol other than the Discord API. Before committing, verify that your interpreter is Python 3.8 or higher, that you have enabled the message content intent in the Discord developer portal, and that your Linux host has libffi-dev and python-dev if you plan to install the voice extra.

Frequently asked questions

What does discord.py do?

It is an API wrapper for Discord written in Python, exposing the Discord API through an async client and a command framework. The README describes it as async ready, with rate limit handling and a Pythonic API built on async and await.

Is discord.py a framework?

The README calls it an API wrapper, not a framework. It does ship a command layer under discord.ext.commands with a commands.Bot class and a @bot.command() decorator, so it provides more than raw endpoint bindings, but you still supply the process, the token and the host.

How to install discord.py on Windows?

The README gives py -3 -m pip install -U discord.py, and py -3 -m pip install -U discord.py[voice] if you want voice support. Python 3.8 or higher is required.

How to install discord.py on Linux?

The README gives python3 -m pip install -U discord.py, and recommends a virtual environment because the system Python on Linux is externally managed. For voice support it also requires libffi-dev and python-dev from your package manager before installing the voice extra.

How to install discord.py?

Install from PyPI with python3 -m pip install -U discord.py, or add the voice extra as discord.py[voice]. The development version is installed by cloning the repository and running python3 -m pip install -U .[voice] inside it.

Is discord.py outdated?

The repository is not archived and its last push was on 2026-09-07, so it is not abandoned. The repository metadata contains no release history, so it cannot be used to judge how quickly new Discord API features are picked up.

Official sources

  1. Issues
  2. License: MIT
  3. Project website
  4. Rapptz/discord.py on GitHub
  5. 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/rapptz-discord-py.svg)](https://hysenlabs.com/projects/rapptz-discord-py)