Discord.js framework
npm install trivious
yarn add trivious
pnpm add triviousRequires Node.js 18+
// src/index.ts
import { TriviousClient, PermissionLevel } from "trivious";
import { GatewayIntentBits } from "discord.js";
const client = new TriviousClient({
tokenReference: "BOT_TOKEN",
clientIdReference: "CLIENT_ID",
corePath: "core", // Folder containing commands/, events/, components/, modules/
intents: [GatewayIntentBits.Guilds],
rolePermissions: { // Altneratively can be set via client.rolePermissions
"123456789012345678": PermissionLevel.GUILD_MODERATOR, // Role ID → PermissionLevel
},
});
(async () => {
try {
await client.register(); // Loads all commands, events, components, modules
await client.deploy(); // Registers slash commands globally
await client.start(); // Logs in
} catch (error) {
console.error("Failed to start bot:", error);
}
})();// src/core/commands/debug/index.ts
import { CommandBuilder, SlashCommand } from "trivious"
export default class DebugCommand extends SlashCommand {
constructor() {
super(new CommandBuilder()
.setName("debug")
.setDescription("Debug tools")
.setGuildOnly()
.setEphemeralReply())
}
};Subcommands go in the same directory as the command file and are auto-detected.
// src/core/commands/debug/ping.ts
import { ChatInputCommandInteraction, Subcommand, SubcommandBuilder, TriviousClient } from "trivious";
export default class DebugPingSubcommand extends Subcommand {
constructor() {
super(new SubcommandBuilder()
.setName("ping")
.setDescription("Ping pong!")
.setOwnerOnly())
}
execute = async (client: TriviousClient, interaction: ChatInputCommandInteraction) => {
try {
const sent = await interaction.fetchReply();
const latency = sent.createdTimestamp - interaction.createdTimestamp;
const apiLatency = Math.round(interaction.client.ws.ping);
await this.reply(interaction, { content: `Pong!\nLatency ${latency}ms API Latency: ${apiLatency}ms` });
} catch (error: any) {
console.error(error);
}
};
};enum PermissionLevel {
USER = 0,
GUILD_STAFF = 1,
GUILD_MODERATOR = 2,
GUILD_ADMINISTRATOR = 3,
GUILD_OWNER = 4,
BOT_OWNER = 5,
}Set role permissions in client options
rolePermissions: {
"987654321098765432": PermissionLevel.GUILD_ADMINISTRATOR,
moderatorRole.id: PermissionLevel.GUILD_MODERATOR,
}Or dynamically at runtime:
client.setRolePermissions({
"123456": PermissionLevel.GUILD_STAFF
})All follow the same, clean consistent pattern.
- Context menus -> extend
ContextMenuCOmmand+ContextMenuBuilder - Buttons/Modals/Select menus -> extend
Component+ useComponentBuilder().setCustomId(...) - Events -> export an object with
name,once?andexecute - Modules -> export an object with events to trigger the module
src/
├── core/
│ ├── commands/
│ │ └── debug/
│ │ ├── index.ts
│ │ └── ping.ts
│ ├── events/
│ │ └── ready.ts
│ ├── components/
│ │ └── ticket-create.ts
│ └── modules/
│ └── logging.ts
└── index.ts