There comes a time in the bot development when you want to extend the bot functionality at run-time and quickly unload and reload code (also called hot-reloading). The command framework comes with this ability built-in, with a concept called extensions.


An extension at its core is a python file with an entry point called setup. This setup function must be a Python coroutine. It takes a single parameter – the Bot that loads the extension.

An example extension looks like this:

from discord.ext import commands

async def hello(ctx):
    await ctx.send(f'Hello {ctx.author.display_name}.')

async def setup(bot):

In this example we define a simple command, and when the extension is loaded this command is added to the bot. Now the final step to this is loading the extension, which we do by calling Bot.load_extension(). To load this extension we call await bot.load_extension('hello').


Extensions are usually used in conjunction with cogs. To read more about them, check out the documentation, Cogs.


Extension paths are ultimately similar to the import mechanism. What this means is that if there is a folder, then it must be dot-qualified. For example to load an extension in plugins/hello.py then we use the string plugins.hello.


When you make a change to the extension and want to reload the references, the library comes with a function to do this for you, Bot.reload_extension().

>>> await bot.reload_extension('hello')

Once the extension reloads, any changes that we did will be applied. This is useful if we want to add or remove functionality without restarting our bot. If an error occurred during the reloading process, the bot will pretend as if the reload never happened.

Cleaning Up

Although rare, sometimes an extension needs to clean-up or know when it’s being unloaded. For cases like these, there is another entry point named teardown which is similar to setup except called when the extension is unloaded.

Exceptions raised in the teardown function are ignored, and the extension is still unloaded.

async def setup(bot):
    print('I am being loaded!')

async def teardown(bot):
    print('I am being unloaded!')