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