# Pycord installs as py-cord and imports as discord, and its voice extra needs system headers first

> An async Discord API wrapper for Python 3.10 through 3.14, MIT licensed. Every package it ships sits under a discord module directory, the version comes from git tags through setuptools-scm, the build pins an upper bound on setuptools, and the funding links in the README and the metadata point at two different places.

**Pycord-Development/pycord** — Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for Discord written in Python

- Repository: https://github.com/Pycord-Development/pycord
- Website: https://docs.pycord.dev
- Stars: 2,959 · Forks: 500
- Language: Python
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/pycord-development-pycord

## The distribution is py-cord and every package lives under discord

The name in the packaging metadata is `py-cord`, with a hyphen, and the description is a Python wrapper for the Discord API. The import name is `discord`, and the examples start with `import discord`.

The `[tool.setuptools]` section lists the packages it ships, and every one of them is under that module name: `discord`, `discord.types`, `discord.sinks`, `discord.ui`, `discord.webhook`, `discord.commands`, `discord.ext.commands`, `discord.ext.tasks`, `discord.ext.pages`, `discord.ext.bridge`, `discord.bin` and `discord.voice`.

That is the practical fact behind every comparison question about this library. Two Discord libraries cannot both own the top-level `discord` module in one environment, so the choice of one is the removal of the other, and virtualenv isolation stops being a convenience and becomes the reason the choice is reversible. The subpackage list also shows the feature surface: pages for paginated views, bridge for bridging command styles, sinks and voice for audio, and a package named `discord.bin`, whose name is left over from a layout that predates the rest.

The repository directory is named `discord/` too, which is why the README's own examples need no import shim.

## Five install routes, two extras, and system packages that must come before pip

Python 3.10 or higher is required, and the documented support range is 3.10 to 3.14, which the classifiers match entry by entry. Without voice support:

```bash
# Linux/macOS
python3 -m pip install -U py-cord

# Windows
py -3 -m pip install -U py-cord
```

With voice support the extra is added, and here the two platforms are written differently. The Linux and macOS line wraps the requirement in quotes, `python3 -m pip install -U "py-cord[voice]"`, while the Windows line does not, `py -3 -m pip install -U py-cord[voice]`. A speedup extra exists with the same shape, and a development route clones the repository and installs `.[voice]` from the checkout, or installs straight from the git URL without cloning.

The part that is not in any of those commands is the system requirement for voice on Linux. Two packages have to be installed through the system package manager before the pip commands run: `libffi-dev`, or `libffi-devel` on some systems, and `python-dev`, with the example given as `python3.10-dev` for Python 3.10. The README states the ordering in capitals.

The example dev package is tied to 3.10 while the library supports through 3.14, so the package name has to track whichever interpreter you actually run. The optional packages behind the extras are PyNaCl for voice, and aiodns with brotlipy and cchardet grouped as an aiohttp speedup, plus msgspec for a JSON speedup.

## The version comes from git tags, and setuptools has an upper bound

The build system requires two packages, and both are pinned on both ends. The first is `setuptools` at `>=77.0.3,<=80.9.0`, and the second is `setuptools-scm` at `>=9.2,<=9.2.2`.

The upper bound on setuptools is the part with operational weight. A build environment with a newer setuptools does not degrade gracefully; the requirement is unsatisfiable, so the install stops. That is a deliberate choice for reproducibility, and it means a base image that updates setuptools eventually needs a pin of its own.

setuptools-scm is what `dynamic = ["version", "dependencies", "optional-dependencies"]` points at. The version is derived from the repository's tags rather than written in a file, and dependencies are read from `requirements/_.txt`, a file whose name is a single character with an extension. So the release number lives in the tag history, which is also why the README's Latest Release badge is built with `sort=semver` and `include_prereleases`: a release candidate such as v2.8.0rc2 can appear in a badge labelled latest release.

setup.py has been reduced to a shim of a few lines that import setup and call it under a main guard, with every piece of metadata living in pyproject.toml.

## Funding is Patreon in the metadata and GitHub Sponsors in the README

The two descriptions of how to support the project point at different services.

In pyproject.toml, the project URLs block lists a Homepage, a Changelog pointing at the documentation site, a Source link, Documentation, a Tracker, and Funding, where the funding entry is a Patreon URL. The README's badge row instead includes a GitHub Sponsors badge targeting the organisation's sponsors page, alongside the PyPI version, Python versions and download badges, a Latest Release badge, a Discord server invite and a Crowdin badge.

So a reader who wants to fund the project from the README lands on GitHub Sponsors, while the packaging metadata that tools read says Patreon.

The Crowdin badges are the other recurring element. One points at a translations site under the project's own domain, and a second, lower in the file, is a translation status image. `crowdin.yml` sits at the repository root to configure it. The packaging classifiers list only English as a natural language, so the translations are community contributions rather than a declared locale set.

Two other root files describe process: `RELEASE_SCHEDULE.md`, a published schedule, and `renovate.json`, the configuration for automated dependency update pull requests.

## The two examples disagree about intents, and the first one is the one people copy

The quick example builds a bot with no configuration at all:

```py
import discord

bot = discord.Bot()

@bot.slash_command()
async def hello(ctx, name: str = None):
    name = name or ctx.author.name
    await ctx.respond(f"Hello {name}!")

@bot.user_command(name="Say Hello")
async def hi(ctx, user):
    await ctx.respond(f"{ctx.author.mention} says hello to {user.name}!")

bot.run("token")
```

The traditional commands example, further down, is the one that configures intents:

```py
import discord
from discord.ext import commands

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

Message content is a privileged intent, and the first example never mentions intents at all. A project that starts from the first snippet and then adds a message-based command has to discover the intent switch on its own, which is the one piece of setup the second example exists to show.

Two more details in the first snippet are worth naming. The respond method is this library's own name for the reply, and the parameter is typed as `str` with a default of `None`, which is an implicitly optional annotation rather than an explicit one. In a project whose classifiers include a Typed marker, that is the example most people copy.

The README also carries one security instruction worth repeating: do not reveal your bot token to anyone, because it can grant access to your bot. Both examples pass the token as a bare string to `bot.run`.

## The README's logo alt text says v3 while the newest release is 2.8.1

The README is `README.rst`, written in reStructuredText with `.. image::` and `.. code::` directives and heading underlines made of equals signs, hyphens and tildes. The first element is a logo image, and its alt text is the version claim: Pycord v3.

The newest release in the repository is v2.8.1, dated 2026-07-25, preceded by v2.8.0 on 2026-05-18 and v2.8.0rc2 on 2026-04-14. So the one place the README states a version number says three, and the tags are on two.

The documentation links carry the same kind of drift. The Useful Links section points at `docs.pycord.dev/en/master/index.html`, with a master path segment, while the changelog URL in the metadata points at the same site under the same path. The homepage recorded for the repository is the bare documentation domain, and the funding, guide and Discord links sit alongside them, including a third-party link described as a high-performance Lavalink wrapper.

None of this breaks anything. It does mean the README's own version marker is not a reliable way to tell which release you are reading about.

## Twenty-seven example files and a docs tree, with a lint setup split across two tools

The examples directory is the practical documentation. It holds an `app_commands/` subdirectory and a `views/` subdirectory, plus individual files for audio recording in two forms, background tasks in asyncio and non-asyncio variants, a basic bot in sync and async versions, voice, bridge commands, community invites, converters, cooldown, a private emoji creator, a custom context, deleted and edited message handlers, modal dialogs, new member events, reaction roles, replies, a secret handler, a soundboard, timeouts and waiting for an event.

That list is the fastest way to see the feature surface without reading the documentation site, and the two audio files and the two background task files suggest the library offers both shapes rather than one.

The tooling is split. Python is linted with flake8, configured in `.flake8` at the root, while `.prettierrc` and a `.pre-commit-config.yaml` handle formatting across the tree. Documentation is built for Read the Docs, configured in `.readthedocs.yml`, from the `docs/` directory. `scripts/` and `tests/` sit beside them, along with `MANIFEST.in` for the packaging manifest and the `pycord.png` logo that the README image directive points at on the master branch.

The import name, the install name and the repository name are three different strings, and that is the single fact to hold on to when reading this project.

## Conclusion

Pycord fits a bot project that wants application commands with an async API and does not need to share an environment with another Discord library, since that is the decision the install forces on you. Three things to check first. The distribution is named `py-cord` and the import is `discord`, so it cannot be installed alongside another library that owns that module name, and uninstalling means deciding which one owns the name in each environment. Voice support is not a pure Python extra: on Linux it needs `libffi-dev` and a Python development package installed through the system package manager before pip runs, in that order. And the build declares an upper bound on setuptools, so a newer setuptools in your build environment is a build failure rather than a warning.

## FAQ

### how to install pycord

Python 3.10 or higher is required. Without voice support, `python3 -m pip install -U py-cord` on Linux and macOS or `py -3 -m pip install -U py-cord` on Windows. With voice support add the extra, as `python3 -m pip install -U "py-cord[voice]"`, and a speedup extra `py-cord[speed]` is also available. On Linux, voice support additionally needs `libffi-dev` or `libffi-devel` plus a Python development package installed before pip runs.

### what is py cord

Pycord is an async ready API wrapper for the Discord API written in Python, distributed on PyPI as `py-cord` and supporting Python 3.10 through 3.14. It is MIT licensed and its advertised features are an async API, rate limit handling, attention to speed and memory, and full application API support.

### What are the differences between discord.py and Pycord?

The repository does not make that comparison. What it does show is that Pycord ships every package under the `discord` module name, listed in pyproject.toml as discord, discord.types, discord.sinks, discord.ui, discord.webhook, discord.commands, several discord.ext subpackages, discord.bin and discord.voice, while the distribution itself is named py-cord. That shared import name is the practical difference between the two libraries.

### Does Pycord need extra packages for voice support?

Yes. The voice extra brings in PyNaCl, and on Linux two system packages must be installed through the system package manager before the pip command runs: libffi-dev, or libffi-devel on some systems, and python-dev, with python3.10-dev given as the example for Python 3.10. The speedup extra is separate and covers aiohttp and JSON handling.

## Sources

- [License: MIT](https://github.com/Pycord-Development/pycord/blob/master/LICENSE)
- [Project website](https://docs.pycord.dev)
- [Pycord-Development/pycord on GitHub](https://github.com/Pycord-Development/pycord)
- [README](https://github.com/Pycord-Development/pycord/blob/master/README.md)
- [Releases](https://github.com/Pycord-Development/pycord/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pycord-development-pycord
