|
| 1 | +--- |
| 2 | +title: Migrating from CommandKit v0 |
| 3 | +description: Learn how to migrate your CommandKit version from v0 to v1 |
| 4 | +--- |
| 5 | + |
| 6 | +import Tabs from '@theme/Tabs'; |
| 7 | +import TabItem from '@theme/TabItem'; |
| 8 | + |
| 9 | +This comprehensive guide will walk you through migrating your Discord bot from CommandKit v0 to v1. CommandKit v1 introduces significant architectural improvements, including a framework-based approach with enhanced developer experience features. |
| 10 | + |
| 11 | +:::info |
| 12 | +This guide uses TypeScript examples, but all concepts apply to JavaScript projects as well. Simply use the corresponding JavaScript file extensions (e.g., `app.js`, `commandkit.config.js`). |
| 13 | +::: |
| 14 | + |
| 15 | +:::warning |
| 16 | +**Minimum Requirements**: CommandKit v1 requires Node.js version 22 or higher. Please ensure your environment meets this requirement before proceeding. |
| 17 | +::: |
| 18 | + |
| 19 | +:::warning |
| 20 | +**Migration Focus**: This guide specifically covers converting existing v0 code to v1. For information about new v1 features and capabilities, please refer to the rest of the documentation after completing your migration. |
| 21 | +::: |
| 22 | + |
| 23 | +## Updating CommandKit |
| 24 | + |
| 25 | +Begin your migration by updating to the latest version of CommandKit: |
| 26 | + |
| 27 | +```bash npm2yarn |
| 28 | +npm install commandkit@latest |
| 29 | +``` |
| 30 | + |
| 31 | +This command will install CommandKit v1 and update your `package.json` with the latest version. |
| 32 | + |
| 33 | +## Project Structure Migration |
| 34 | + |
| 35 | +CommandKit v1 adopts a framework-based approach with a structured `app` directory that serves as the primary location for your bot's functionality. This new structure provides better organization and enables advanced features like automatic route discovery. |
| 36 | + |
| 37 | +<Tabs> |
| 38 | + <TabItem value="v1" label="v1 (New Structure) ✅" default> |
| 39 | + ``` |
| 40 | + . |
| 41 | + ├── src/ |
| 42 | + │ ├── app/ |
| 43 | + │ │ ├── commands/ |
| 44 | + │ │ │ └── ping.ts |
| 45 | + │ │ └── events/ |
| 46 | + │ │ └── ready/ |
| 47 | + │ │ └── log.ts |
| 48 | + │ └── app.ts |
| 49 | + ├── .env |
| 50 | + ├── commandkit.config.ts |
| 51 | + ├── package.json |
| 52 | + └── tsconfig.json |
| 53 | + ``` |
| 54 | + |
| 55 | + </TabItem> |
| 56 | + <TabItem value="v0" label="v0 (Legacy Structure) ❌"> |
| 57 | + ``` |
| 58 | + . |
| 59 | + ├── src/ |
| 60 | + │ ├── commands/ |
| 61 | + │ │ └── ping.ts |
| 62 | + │ └── events/ |
| 63 | + │ └── ready/ |
| 64 | + │ └── log.ts |
| 65 | + ├── .env |
| 66 | + ├── commandkit.config.mjs |
| 67 | + ├── package.json |
| 68 | + └── tsconfig.json |
| 69 | + ``` |
| 70 | + |
| 71 | + </TabItem> |
| 72 | +</Tabs> |
| 73 | + |
| 74 | +## Configuration File Updates |
| 75 | + |
| 76 | +CommandKit v1 significantly simplifies configuration by automatically detecting your project structure and entry points. The framework now supports a standardized set of configuration file names for consistency. |
| 77 | + |
| 78 | +**Supported Configuration Files:** |
| 79 | + |
| 80 | +- `commandkit.config.js` |
| 81 | +- `commandkit.config.mjs` |
| 82 | +- `commandkit.config.cjs` |
| 83 | +- `commandkit.config.ts` |
| 84 | + |
| 85 | +<Tabs> |
| 86 | + <TabItem value="v1" label="v1 (Simplified Config) ✅" default> |
| 87 | + ```ts title='commandkit.config.ts' |
| 88 | + import { defineConfig } from 'commandkit'; |
| 89 | + |
| 90 | + export default defineConfig({ |
| 91 | + // Configuration is now optional for most use cases |
| 92 | + // CommandKit automatically detects your app structure |
| 93 | + }); |
| 94 | + ``` |
| 95 | + |
| 96 | + </TabItem> |
| 97 | + <TabItem value="v0" label="v0 (Manual Config) ❌"> |
| 98 | + ```ts title='commandkit.config.mjs' |
| 99 | + import { defineConfig } from 'commandkit'; |
| 100 | + |
| 101 | + export default defineConfig({ |
| 102 | + src: 'src', |
| 103 | + main: 'index.mjs', |
| 104 | + // Manual configuration was required |
| 105 | + }); |
| 106 | + ``` |
| 107 | + |
| 108 | + </TabItem> |
| 109 | +</Tabs> |
| 110 | + |
| 111 | +:::info |
| 112 | +The CommandKit CLI commands (`commandkit dev`, `commandkit build`, `commandkit start`) continue to work seamlessly with the new configuration system. |
| 113 | +::: |
| 114 | + |
| 115 | +## Entry Point Transformation |
| 116 | + |
| 117 | +CommandKit v1 introduces a dramatically simplified entry point system. Instead of manually managing the CommandKit instance, bot login, and path configurations, you now simply export a configured Discord.js client. |
| 118 | + |
| 119 | +<Tabs> |
| 120 | + <TabItem value="v1" label="v1 (Streamlined Entry) ✅" default> |
| 121 | + ```ts title='src/app.ts' |
| 122 | + import { Client } from 'discord.js'; |
| 123 | + |
| 124 | + const client = new Client({ |
| 125 | + intents: [ |
| 126 | + 'Guilds', |
| 127 | + 'GuildMessages', |
| 128 | + 'MessageContent', |
| 129 | + ], |
| 130 | + }); |
| 131 | + |
| 132 | + // Optional: Override the default token environment variable |
| 133 | + client.token = process.env.CUSTOM_TOKEN_VAR; |
| 134 | + |
| 135 | + export default client; // CommandKit handles the rest automatically |
| 136 | + ``` |
| 137 | + |
| 138 | + </TabItem> |
| 139 | + <TabItem value="v0" label="v0 (Manual Setup) ❌"> |
| 140 | + ```ts title='src/index.ts' |
| 141 | + import { Client, GatewayIntentBits } from 'discord.js'; |
| 142 | + import { CommandKit } from 'commandkit'; |
| 143 | + import path from 'path'; |
| 144 | + |
| 145 | + const client = new Client({ |
| 146 | + intents: [ |
| 147 | + 'Guilds', |
| 148 | + 'GuildMessages', |
| 149 | + 'MessageContent', |
| 150 | + ], |
| 151 | + }); |
| 152 | + |
| 153 | + new CommandKit({ |
| 154 | + client, |
| 155 | + commandsPath: path.join(__dirname, 'commands'), |
| 156 | + eventsPath: path.join(__dirname, 'events'), |
| 157 | + validationsPath: path.join(__dirname, 'validations'), |
| 158 | + skipBuiltInValidations: true, |
| 159 | + bulkRegister: true, |
| 160 | + }); |
| 161 | + |
| 162 | + client.login('YOUR_TOKEN_HERE'); |
| 163 | + ``` |
| 164 | + |
| 165 | + </TabItem> |
| 166 | +</Tabs> |
| 167 | + |
| 168 | +## Command File Structure |
| 169 | + |
| 170 | +CommandKit v1 modernizes the command API with more intuitive naming and cleaner type definitions. The new structure separates command metadata from execution logic more clearly, while introducing room for new APIs such as message (legacy) commands. |
| 171 | + |
| 172 | +<Tabs> |
| 173 | + <TabItem value="v1" label="v1 (Modern API) ✅" default> |
| 174 | + ```ts title='src/app/commands/ping.ts' |
| 175 | + import type { CommandData, ChatInputCommandContext } from 'commandkit'; |
| 176 | + |
| 177 | + export const command: CommandData = { |
| 178 | + name: 'ping', |
| 179 | + description: 'Pong!', |
| 180 | + }; |
| 181 | + |
| 182 | + export function chatInput({ interaction }: ChatInputCommandContext) { |
| 183 | + interaction.reply('Pong!'); |
| 184 | + } |
| 185 | + ``` |
| 186 | + |
| 187 | + </TabItem> |
| 188 | + <TabItem value="v0" label="v0 (Legacy API) ❌"> |
| 189 | + ```ts title='src/commands/ping.ts' |
| 190 | + import type { CommandData, SlashCommandProps } from 'commandkit'; |
| 191 | + |
| 192 | + export const data: CommandData = { |
| 193 | + name: 'ping', |
| 194 | + description: 'Pong!', |
| 195 | + }; |
| 196 | + |
| 197 | + export function run({ interaction }: SlashCommandProps) { |
| 198 | + interaction.reply('Pong!'); |
| 199 | + } |
| 200 | + ``` |
| 201 | + |
| 202 | + </TabItem> |
| 203 | +</Tabs> |
| 204 | + |
| 205 | +## Middleware System (Formerly Validations) |
| 206 | + |
| 207 | +CommandKit v1 renames and enhances the validation system to "middleware," which better reflects its purpose and capabilities. Middleware can now run in various contexts and provides more granular control over command execution. |
| 208 | + |
| 209 | +<Tabs> |
| 210 | + <TabItem value="v1" label="v1 (Middleware System) ✅" default> |
| 211 | + ```ts title='src/app/commands/+global-middleware.ts' |
| 212 | + import type { MiddlewareContext } from 'commandkit'; |
| 213 | + |
| 214 | + export function beforeExecute(ctx: MiddlewareContext) { |
| 215 | + // Example: Block command execution based on conditions |
| 216 | + if (ctx.interaction.isRepliable()) { |
| 217 | + ctx.interaction.reply('Access denied: Command execution blocked.'); |
| 218 | + } |
| 219 | + |
| 220 | + ctx.cancel(); // Prevents command execution |
| 221 | + } |
| 222 | + ``` |
| 223 | + |
| 224 | + </TabItem> |
| 225 | + <TabItem value="v0" label="v0 (Validation System) ❌"> |
| 226 | + ```ts title='src/validations/block-execution.ts' |
| 227 | + import type { ValidationProps } from 'commandkit'; |
| 228 | + |
| 229 | + export default function (ctx: ValidationProps) { |
| 230 | + if (ctx.interaction.isRepliable()) { |
| 231 | + ctx.interaction.reply('You are blocked from running the command!'); |
| 232 | + } |
| 233 | + return true; // command will not be executed |
| 234 | + }; |
| 235 | + ``` |
| 236 | + |
| 237 | + </TabItem> |
| 238 | +</Tabs> |
| 239 | + |
| 240 | +For comprehensive middleware documentation, including command-specific and conditional middleware, refer to the [middleware documentation](../07-file-system-conventions/02-+middleware.ts.mdx). |
| 241 | + |
| 242 | +## Development Environment |
| 243 | + |
| 244 | +CommandKit v1 introduces advanced development features that require using the CommandKit CLI. The development server provides Hot Module Replacement (HMR) for rapid iteration and supports modern features like JSX components. |
| 245 | + |
| 246 | +### Starting Development Server |
| 247 | + |
| 248 | +```bash npm2yarn |
| 249 | +npx commandkit dev |
| 250 | +``` |
| 251 | + |
| 252 | +:::warning |
| 253 | +**Generated Files**: The development server creates a `.commandkit` directory for temporary files. Add this to your `.gitignore` to prevent committing generated files: |
| 254 | + |
| 255 | +```gitignore |
| 256 | +.commandkit/ |
| 257 | +``` |
| 258 | + |
| 259 | +::: |
| 260 | + |
| 261 | +## Production Deployment |
| 262 | + |
| 263 | +### Building Your Application |
| 264 | + |
| 265 | +```bash npm2yarn |
| 266 | +npx commandkit build |
| 267 | +``` |
| 268 | + |
| 269 | +### Starting Production Application |
| 270 | + |
| 271 | +Option 1 - Using CommandKit CLI (Recommended): |
| 272 | + |
| 273 | +```bash npm2yarn |
| 274 | +npx commandkit start |
| 275 | +``` |
| 276 | + |
| 277 | +Option 2 - Direct Node.js execution: |
| 278 | + |
| 279 | +```bash |
| 280 | +node dist/index.js |
| 281 | +``` |
| 282 | + |
| 283 | +:::warning |
| 284 | +**Generated Build Files**: The build process creates a `dist` directory. Add this to your `.gitignore` to prevent committing build artifacts: |
| 285 | + |
| 286 | +```gitignore |
| 287 | +dist/ |
| 288 | +``` |
| 289 | + |
| 290 | +::: |
0 commit comments