The djs.config.ts file is the heart of your djs-core project. It defines secrets, Discord gateway settings, database, plugins, and experimental flags.

djs.config.ts

Use defineConfig from @djs-core/runtime for full type inference on plugins and pluginsConfig:

import { defineConfig } from "@djs-core/runtime";
import { IntentsBitField, InteractionContextType } from "discord.js";
if (!process.env.TOKEN) {
throw new Error("TOKEN environment variable is required");
}
export default defineConfig({
token: process.env.TOKEN,
servers: ["YOUR_GUILD_ID"],
intents: [IntentsBitField.Flags.Guilds],
commands: {
defaultContext: [InteractionContextType.Guild],
},
});

You can also use satisfies Config from @djs-core/dev if you do not need plugin type inference.

Core options

tokenstringrequired

Your Discord bot token from the Discord Developer Portal.

serversstring[]required

Guild IDs where slash commands and context menus are registered.

  • Specific guild IDs → near-instant updates during development.
  • Empty array [] → global commands (can take up to 1 hour to propagate).

Never commit your bot token. Store it in .env and add .env to .gitignore.

Gateway: intents & partials

The runtime defaults to Guilds intent only and no partials. Add what your bot actually listens to.

import { IntentsBitField, Partials } from "discord.js";
export default defineConfig({
// ...
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.MessageContent,
IntentsBitField.Flags.GuildMembers,
],
partials: [Partials.Message, Partials.Channel],
});
Intent Needed for
Guilds Default — slash commands, basic guild data
GuildMessages messageCreate and message content
MessageContent Reading message text (privileged)
GuildMembers Member join/leave events, member lists

Enable matching intents in the Discord Developer Portal under Bot → Privileged Gateway Intents.

Command defaults

commands: {
defaultContext: [InteractionContextType.Guild],
},

Sets where new slash commands are available by default (guild only, DMs, etc.). Override per command with .setContexts() on the Command builder.

Database

db: {
dialect: "sqlite", // sqlite | postgresql | mysql | turso
url: "file:./db.sqlite", // optional
autoMigrate: false, // default — prefer CI migrations in prod
},

Adds interaction.client.db with Drizzle. See Database.

Plugins

import { myPlugin } from "my-djs-plugin";
export default defineConfig({
plugins: [myPlugin],
pluginsConfig: {
myPlugin: {
apiKey: process.env.MY_PLUGIN_KEY,
},
},
});

defineConfig infers pluginsConfig keys from each plugin’s name. Third-party plugins attach APIs to interaction.client.<pluginName>. See Plugins.

Official database plugins are deprecated — use native db: instead. See Migrate from plugins.

Experimental features

Flag Purpose
experimental.cron Enable src/cron/ tasks — Cron Tasks
experimental.userConfig Load config.json into client.config — User Config
experimental.bundle Embed config.json in production builds — Bundle

Environment variables

TOKEN=your_discord_bot_token_here
DATABASE_URL=postgresql://... # when using postgresql dialect

Bun loads .env automatically — no dotenv needed.

Development hot reload

djs-core dev hot-reloads handlers under src/. It does not reload djs.config.ts changes.

After editing djs.config.ts (token, servers, db, plugins, intents, experimental flags), restart djs-core dev.

config.json is different — when experimental.userConfig is enabled, types regenerate on save, but restart dev to pick up new runtime values.

During long dev sessions, Bun keeps cache-busted module imports in memory. Restart djs-core dev if memory grows.

Full example

import { demoPlugin } from "my-djs-plugin";
import { defineConfig } from "@djs-core/runtime";
import { IntentsBitField, InteractionContextType } from "discord.js";
export default defineConfig({
token: process.env.TOKEN!,
servers: ["YOUR_GUILD_ID"],
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.MessageContent,
],
commands: {
defaultContext: [InteractionContextType.Guild],
},
db: {
dialect: "sqlite",
},
plugins: [demoPlugin],
pluginsConfig: {
demo: { message: "hello" },
},
experimental: {
cron: true,
userConfig: true,
},
});