detritus
detritus-client 0.17.0-beta.120

Discord bots in TypeScript, from the gateway up.

A full client with caching, prefix and slash commands, components and voice, built from small packages you can also use on their own.

$npm install detritus-client

Requires Node 22.19 or newer.

import { CommandClient } from 'detritus-client';

const commandClient = new CommandClient(process.env.TOKEN!, {
  prefix: '..',
});

commandClient.add({
  name: 'ping',
  run: (context) => context.reply('pong!'),
});

commandClient.add({
  name: 'owner',
  onBefore: (context) => context.client.isOwner(context.userId),
  onCancel: (context) => context.reply('Owner only, sorry.'),
  run: (context) => context.reply('Hello, owner.'),
});

(async () => {
  const client = await commandClient.run();
  console.log(`Running ${client.shardCount} shards`);
})();
const { CommandClient } = require('detritus-client');

const commandClient = new CommandClient(process.env.TOKEN, {
  prefix: '..',
});

commandClient.add({
  name: 'ping',
  run: (context) => context.reply('pong!'),
});

commandClient.add({
  name: 'owner',
  onBefore: (context) => context.client.isOwner(context.userId),
  onCancel: (context) => context.reply('Owner only, sorry.'),
  run: (context) => context.reply('Hello, owner.'),
});

(async () => {
  const client = await commandClient.run();
  console.log(`Running ${client.shardCount} shards`);
})();
Prefix commands with a CommandClient·Read more
// what's in the box

The boring parts, handled

Utils.Components

Buttons and menus that call you back

Give a component a run function and it's called when someone uses it. No matching custom ids by hand, and timeouts clean up after themselves.

const components = new Utils.Components({
  timeout: 5 * 60 * 1000,
  onTimeout: () => context.editOrRespond({content: 'Too slow!', components: []}),
});

components.createButton({
  label: 'Click me',
  run: (button) => button.editOrRespond({
    content: `Clicked by ${button.user}`,
    components: [],
  }),
});

await context.editOrRespond({content: 'Go ahead', components});
sharding

Scale without rewriting

Start with one shard and grow into processes. The event API stays the same.

detritus-client-rest

Every endpoint is a method

Requests queue per ratelimit bucket and retry after a 429, global and shared limits included.

366 methods on one Client
caching

Caches you control

Every collection can be capped, expired or switched off, from messages to presences.

voice

Voice with DAVE

Join, send and receive audio with Discord's end-to-end encryption, and mix users together with AudioMixer.

typescript

Typed all the way down

Written in TypeScript, from raw gateway payloads in GatewayRawEvents up to every structure.