Plugins
Extend your bot with definePlugin — third-party plugins and plugin authoring.
Official @djs-core/plugin-* packages are deprecated (database plugins: drizzle, sql, prisma-sqlite). They will be removed in an upcoming major release.
Use native Database with db: and client.db instead. See Migrate from plugins.
The Plugin Marketplace is legacy reference only — do not start new projects on official DB plugins.
Third-party plugins via definePlugin are still supported. Use them to share logic across bots and attach typed APIs to interaction.client.
Install a plugin
djs-core plugin install my-package# or full scope:djs-core plugin install @scope/my-djs-pluginThis runs bun add, patches djs.config.ts when possible, and runs the plugin postinstall hook.
Use a plugin
import { defineConfig } from "@djs-core/runtime";import { myPlugin } from "my-djs-plugin";
export default defineConfig({ token: process.env.TOKEN!, servers: ["YOUR_GUILD_ID"], plugins: [myPlugin], pluginsConfig: { myPlugin: { apiKey: process.env.MY_PLUGIN_KEY, }, },});defineConfig infers pluginsConfig keys from each plugin’s name. Access the extension on interaction.client.myPlugin inside handlers.
Create a plugin
import { definePlugin } from "@djs-core/runtime";import packageJson from "./package.json" with { type: "json" };
export interface MyPluginConfig { apiKey: string;}
export const myPlugin = definePlugin({ name: "myPlugin", packageName: packageJson.name, setup(_client, config: MyPluginConfig) { return { ping: () => `ok (${config.apiKey.slice(0, 4)}…)`, }; }, onReady(_client, _config, extension) { console.log("[myPlugin] ready", extension.ping()); }, types: () => `declare module "@djs-core/runtime" { interface PluginsExtensions { myPlugin: { ping: () => string; }; }}`, postinstall: async ({ root }) => { // optional — scaffold files, print setup steps, etc. console.log(`myPlugin installed in ${root}`); },});Required fields
| Field | Description |
|---|---|
name |
Key used in pluginsConfig and client.<name> |
packageName |
npm package name — used for runtime semver validation against peerDependencies["@djs-core/runtime"] |
setup(client, config) |
Runs before login. Return value is attached to client |
Optional hooks
| Hook | Description |
|---|---|
onReady(client, config, extension) |
After the bot is ready |
types({ root }) |
TypeScript declarations merged into .djscore/ |
postinstall({ root }) |
Runs after djs-core plugin install |
cli(cac) |
Register extra CLI commands on the shared djs-core binary |
Run djs-core generate-config-types after changing plugin types.
Plugin API changes are tracked separately from runtime bugfixes in PLUGIN_API_CHANGELOG.md on GitHub.
When to use plugins vs native features
| Need | Use |
|---|---|
| Database (SQLite, Postgres, MySQL, Turso) | Native db: — not a plugin |
| Shared bot utilities, integrations, custom APIs | definePlugin |
Official @djs-core/plugin-drizzle etc. |
Deprecated — migrate |
Prefer native db: for databases. Reserve plugins for logic that does not belong in the core framework.