DJS Commandsv2 docs
Migration from v1

Persistence

Mongoose schemas → Storage adapters

Persistence

v1 baked Mongoose into the framework with 7 hardcoded schemas. v2 splits storage out behind a generic Storage contract — pick @djs-commands/adapter-drizzle, @djs-commands/adapter-prisma, or @djs-commands/adapter-mongoose (the v1 continuity path).

Mongoose continuity

If you want to keep using Mongoose:

bun add @djs-commands/adapter-mongoose mongoose
import { storage } from "./storage";

createCommandHandler({
    client,
    storage,
    // …
});

Define your own Mongoose schemas/models, then map framework logical fields in mongooseStorage({ models }). You can swap to Drizzle/Postgres or Prisma later by changing storage wiring and migrations.

Schema mapping

v1 collectionv2 modelWhat changed
cooldowns(in-memory + optional CacheAdapter)Cooldowns no longer hit the DB by default. Use @djs-commands/adapter-redis for sharded bots.
guild-prefix-schemaGuildPrefixModelResolved when storageFeatures.guildPrefixes is enabled. It defaults from legacy.enabled, but can be configured.
disabled-commands-schemaDisabledCommandsModelRequires storageFeatures.disabledCommands.
channel-commands-schemaChannelLocksModelRequires storageFeatures.channelLocks.
custom-command-schemadroppedThe custom-commands feature is gone.
required-permissions-schemadroppedUse the permissions property on defineCommand (static) or canRunCommand for runtime gating.
required-roles-schemadroppedUse the roles property on defineCommand (static) or canRunCommand.

Programmatic prefix / disabled / locks

v1 commands like /prefix, /togglecommand, /channelonly were built into the framework. v2 ships them as helpers so you can build admin commands of your own:

import {
    setGuildPrefix,
    disableCommand,
    enableCommand,
    lockCommandToChannel,
    unlockCommandFromChannel,
} from "@djs-commands/core";

await setGuildPrefix(storage, guildId, "?");
await disableCommand(storage, guildId, "ban");
await lockCommandToChannel(storage, guildId, "ban", channelId);

Switching adapters later

Because handler code only receives storage, moving from Mongo to Postgres later means changing storage wiring:

- import { storage } from "./mongoose-storage";
+ import { drizzleStorage } from "@djs-commands/adapter-drizzle";
+ import { GuildPrefixModel } from "@djs-commands/core";
+ import { drizzle } from "drizzle-orm/node-postgres";
+ import pg from "pg";
+ import { guildPrefixes } from "./schema";
+ const db = drizzle(new pg.Pool({ connectionString: process.env.DATABASE_URL }));
+ const storage = drizzleStorage(db, {
+     models: {
+         [GuildPrefixModel]: {
+             table: guildPrefixes,
+             fields: { guild_id: guildPrefixes.guildId, prefix: guildPrefixes.prefix },
+         },
+     },
+ });

  createCommandHandler({
      client,
      storage,
  });

Plus, of course, writing the new schema/migration.

Last updated on

On this page