djs-commandsv2 docs
Migration from v1

Handler options

Mapping every v1 CommandHandler option to v2

Handler options

Every option you passed to new CommandHandler({ … }) in v1 has a mapping in v2.

v1 optionv2 equivalent
clientclient (unchanged)
mongoUristorage: mongooseStorage(connection) from @djs-commands/adapter-mongoose
commandDircommandDir (unchanged — fs-autoloader is still the default)
featuresDirplugins: [...] — see Events and plugins
events.direventDir
defaultPrefixlegacy: { enabled: true, defaultPrefix: "!" }
botOwnersbotOwners (unchanged)
cooldownConfigper-command cooldown: { type, duration } (no global config)
testServersdropped — handle via your own deploy logic per guild
defaultCommanddropped — built-in admin commands removed; build your own
antiCrashdropped — use process-level unhandledRejection / uncaughtException

Worked example

// v1
import CommandHandler from "@d3oxy/djs-commands";
import { Client, IntentsBitField } from "discord.js";

const client = new Client({
    intents: [
        IntentsBitField.Flags.Guilds,
        IntentsBitField.Flags.GuildMessages,
        IntentsBitField.Flags.MessageContent,
    ],
});

client.on("ready", () => {
    new CommandHandler({
        client,
        mongoUri: process.env.MONGO_URI,
        commandDir: path.join(__dirname, "commands"),
        featuresDir: path.join(__dirname, "features"),
        defaultPrefix: "!",
        botOwners: ["123…"],
        events: { dir: path.join(__dirname, "events") },
        cooldownConfig: { dbRequired: 300 },
    });
});

client.login(process.env.TOKEN);
// v2
import { createCommandHandler } from "@djs-commands/core";
import { mongooseStorage } from "@djs-commands/adapter-mongoose";
import { Client, GatewayIntentBits } from "discord.js";
import { fileURLToPath } from "node:url";
import mongoose from "mongoose";

const client = new Client({
    intents: [
        GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.MessageContent,
    ],
});

const connection = mongoose.createConnection(process.env.MONGO_URI!);

createCommandHandler({
    client,
    storage: mongooseStorage(connection),
    commandDir: fileURLToPath(new URL("./commands", import.meta.url)),
    eventDir: fileURLToPath(new URL("./events", import.meta.url)),
    legacy: { enabled: true, defaultPrefix: "!" },
    botOwners: ["123…"],
    // cooldowns are per-command in v2 — no global config
});

await client.login(process.env.TOKEN!);

Notes:

  • v2 doesn't wait for ready to wire up — you call createCommandHandler synchronously after constructing the Client.
  • v2's commandDir accepts a path string. We use fileURLToPath(new URL(...)) so it works under both Bun and Node + tsx; v1's path.join(__dirname, ...) worked because v1 was CJS — v2 is ESM.
  • cooldownConfig.dbRequired (v1's "use DB if duration ≥ 5min") doesn't exist. Cooldowns default to in-memory; provide a cacheAdapter (e.g. @djs-commands/adapter-redis) for distributed cooldowns.

On this page