Chooksie

Welcome to Chooksie! The fastest way to create modern Discord Bots with all the latest features like Slash Commands and Autocompletes, while still maintaning the ease and simplicity of developing the now deprecated Legacy (Message) Commands.

The Problem

Back then, writing Discord bots were much more simpler, but also much less structured. This had the advantage that those completely new to programming were able to dive in with using the Discord.JS library, but also having the disadvantage of following multiple, often conflicting guides.

This was when Discord.JS frameworks like Commandoopen in new window and Akairoopen in new window began to surface, aiming to streamline the process of creating Discord bots.

Fast forward to 2021, Discord announces that Message Content will now become a Privileged Intentopen in new window and the new Slash Commandsopen in new window feature, effectively forcing most bot owners to move to the new API.

These updates have caused a massive shift in the way Discord bots are written. User inputs are now built in and command discoverability is now handled by the Discord client, but introduces the added complexity of requiring your bot to constantly syncopen in new window to Discord's API.

This is where Chooksie comes in. Our goal is to streamline the process again, integrating hot code reloads with real-time command syncing: resulting in removing multiple repetitive steps which adds up to saving minutes of what otherwise would have been you staring at your screen.

How Does This Help Me Write Bots Faster?

Chooksie was built from the ground up for the new Application Commandsopen in new window system, this means we don't have the burden of having to maintain compatibility with Legacy Commands, allowing us to optimize for working with Application Commands.

How much optimization have we achieved with this? Here's a side-by-side code comparison against the popular Sapphireopen in new window Framework implementing the basic /ping Slash Command:

Using @sapphire/framework

import { Command } from '@sapphire/framework'
import type { CommandInteraction } from 'discord.js'

export class PingCommand extends Command {
  public constructor(context: Command.Context) {
    super(context, {
      description: 'Pong!',
      chatInputCommand: {
        register: true,
      },
    })
  }
  public async chatInputRun(interaction: CommandInteraction) {
    await interaction.reply('Pong!')
  }
}
import { Command } from '@sapphire/framework'

export class PingCommand extends Command {
  constructor(context) {
    super(context, {
      description: 'Pong!',
      chatInputCommand: {
        register: true,
      },
    })
  }
  async chatInputRun(interaction) {
    await interaction.reply('Pong!')
  }
}

Using Chooksie

import { defineSlashCommand } from 'chooksie'

export default defineSlashCommand({
  name: 'ping',
  description: 'Pong!',
  async execute(ctx) {
    await ctx.interaction.reply('Pong!')
  },
})
export default {
  name: 'ping',
  description: 'Pong!',
  async execute(ctx) {
    await ctx.interaction.reply('Pong!')
  },
}

As you can see, Chooksie uses plain objects to define your commands, only requiring the developer to define the bare minimum needed to register commands.

Not only does using plain objects makes for tinier, declarative command definitions, but it also allows us to take advantage of TypeScript interfaces and provide type information to JavaScript files, as seen in the Type-Safe Chooksie example, where no special TypeScript syntax were used.