DiscordKit and discordgo
DiscordKit and discordgo solve different parts of the same problem.
DiscordKit is built on top of discordgo and intentionally keeps the underlying library visible.
Understanding this relationship makes the rest of the framework much easier to reason about.
The layers
Section titled “The layers”A simplified DiscordKit application looks like this:
┌───────────────────────────┐│ Your application │├───────────────────────────┤│ DiscordKit ││ ││ Router · Context ││ Commands · Components ││ Forms · Middleware ││ Response lifecycle │├───────────────────────────┤│ discordgo ││ ││ Gateway · REST ││ Sessions · Discord types │├───────────────────────────┤│ Discord API │└───────────────────────────┘discordgo provides the protocol and data-model layer.
DiscordKit provides application structure around interactions.
What remains discordgo
Section titled “What remains discordgo”DiscordKit does not define alternative models for Discord entities.
For example:
user, err := c.RequireUserOption("user")returns:
*discordgo.UserA resolved channel is:
*discordgo.ChannelA guild member is:
*discordgo.MemberAnd your application owns the original:
*discordgo.SessionThis is intentional.
Wrapping all of these types would create another object model that developers would constantly need to convert back into discordgo values.
DiscordKit avoids that duplication.
What DiscordKit adds
Section titled “What DiscordKit adds”DiscordKit focuses on patterns that tend to live above discordgo.
Routing
Section titled “Routing”Instead of manually branching on interaction types and custom IDs, register handlers:
router.Command("ping", pingHandler)
router.Component( "/jobs/:jobID/save", saveJobHandler,)
router.Modal( "/jobs/:jobID/edit", editJobHandler,)Context
Section titled “Context”Raw Discord interaction data is wrapped in an application-oriented Context.
For example:
name, ok := c.String("name")
user, err := c.RequireUserOption("user")
jobID := c.MustParam("jobID")Builders
Section titled “Builders”DiscordKit provides builders for application commands, options, Components V2, and modal forms.
The result is still compatible with discordgo.
Lifecycle management
Section titled “Lifecycle management”DiscordKit tracks interaction response state and prevents common invalid sequences.
For example, sending two initial responses returns:
discordkit.ErrAlreadyRespondedMiddleware
Section titled “Middleware”Reusable application behavior can be applied consistently around handlers:
router := discordkit.NewRouter( discordkit.Recovery(), discordkit.Logging(nil),)You can always drop down to discordgo
Section titled “You can always drop down to discordgo”DiscordKit is intentionally not a closed abstraction.
Inside a handler, the underlying session and interaction remain available.
This means a DiscordKit application can use any discordgo functionality even when DiscordKit does not provide a dedicated abstraction for it.
This design is sometimes called an escape hatch.
It is particularly useful when:
- Discord introduces a new API feature;
- discordgo supports something before DiscordKit does;
- you need low-level REST functionality;
- an application has unusual requirements that do not fit a framework helper.
Existing discordgo applications
Section titled “Existing discordgo applications”You do not need to rewrite an existing discordgo application to adopt DiscordKit.
The router itself is attached as a regular discordgo handler:
session.AddHandler(router.Handle)Existing handlers can remain registered:
session.AddHandler(existingMessageHandler)session.AddHandler(existingReadyHandler)session.AddHandler(router.Handle)This makes incremental adoption possible.
A useful rule of thumb
Section titled “A useful rule of thumb”Use DiscordKit when the problem is primarily about application interaction structure:
- routes;
- handlers;
- command declarations;
- components;
- forms;
- middleware;
- response state.
Use discordgo directly when the problem is primarily about Discord itself:
- sessions;
- Gateway events;
- Discord entities;
- REST endpoints;
- low-level or newly introduced Discord features.
In practice, well-designed DiscordKit applications use both.