Spraxium logoSpraxium

Crea bots de Discord
como software real.

Spraxium agrega la capa de arquitectura que Discord.js no proporciona: módulos, inyección de dependencias, pipelines de guards y comandos tipados. Un modelo, todos los tipos de interacción.

Code editor preview showing a Spraxium bot project
src/main.ts
1import { IntentPreset, SpraxiumFactory } from '@spraxium/core';
2import { EnvValidator } from '@spraxium/env';
3import { Logger } from '@spraxium/logger';
4import { AppEnv } from './app.env';
5import { AppModule } from './app.module';
6
7async function main() {
8 const logger = new Logger('Main');
9 const environment = EnvValidator.validate(AppEnv);
10
11 const app = await SpraxiumFactory.create({ token: environment.token });
12 app.useModule(AppModule);
13 app.provide(AppEnv, environment);
14 app.intents(IntentPreset.Standard);
15
16 logger.info('Starting application...');
17 await app.listen();
18}
19
20main();

Módulos con límites bien definidos, providers inyectados y un contenedor de DI que resuelve todo de forma determinista al arranque.

Combina módulos entre dominios, comparte providers y aplica guards a cualquier tipo de interacción con un solo decorator.

Cada provider se conecta a onBoot(), onReady() y onShutdown(). Sin orden de inicialización oculta ni condiciones de carrera.

Escribe la lógica de permisos una vez como clase guard y aplícala a slash commands, context menus y prefix commands con un solo decorator.

Cada opción de comando, payload de interacción y contrato de provider está totalmente tipado. Sin castings, sin any, sin sorpresas en runtime.

Los providers son clases inyectables puras con dependencias declaradas. Cambia implementaciones reales por mocks en test sin tocar el código de producción.

Comparativa de arquitectura

Menos complejidad a medida que tu bot crece.

À medida que un proyecto escala más allá de unos pocos comandos, discord.js requiere un cableado manual creciente - guards, DI, scheduling y estado, todo hecho a mano. Spraxium se encarga de esa capa.

Spraxium
Sapphire
discord.js
Complejidad0255075100Hello World5 CommandsServicesProduction

* Estimaciones ilustrativas de complejidad basadas en líneas de código de infraestructura requeridas por hito en un proyecto de bot de producción típico.

La Brecha Arquitectural

Mismo comando. Mundo diferente.

El mismo comando /ban, implementado dos veces. Una con discord.js puro, otra con Spraxium. La diferencia no es sintaxis. Es estructura, seguridad y escala.

1// 1. Register the slash command with Discord
2const { REST, Routes, SlashCommandBuilder } = require('discord.js');
3
4const command = new SlashCommandBuilder()
5 .setName('ban')
6 .setDescription('Ban a member from the server.')
7 .addUserOption(opt =>
8 opt.setName('user').setDescription('Target').setRequired(true))
9 .addStringOption(opt =>
10 opt.setName('reason').setDescription('Reason'));
11
12const rest = new REST().setToken(process.env.DISCORD_TOKEN);
13await rest.put(Routes.applicationCommands(CLIENT_ID), {
14 body: [command.toJSON()],
15});
16
17// 2. Handle the interaction at runtime
18client.on('interactionCreate', async (interaction) => {
19 if (!interaction.isChatInputCommand()) return;
20 if (interaction.commandName !== 'ban') return;
21
22 if (!interaction.memberPermissions?.has('BanMembers')) {
23 return interaction.reply({ content: 'No permission.', flags: 'Ephemeral' });
24 }
25
26 const target = interaction.options.getUser('user', true);
27 const reason = interaction.options.getString('reason') ?? 'No reason';
28 const member = interaction.guild?.members.cache.get(target.id);
29
30 if (!member) {
31 return interaction.reply({ content: 'User not found.', flags: 'Ephemeral' });
32 }
33
34 await member.ban({ reason });
35 await interaction.reply(`Banned ${target.tag}.`);
36});
  • Registro y handler totalmente desacoplados: sin vínculo estructural entre ambos
  • Checks de permisos escritos a mano en cada handler, sin enforcement ni reutilización
  • Todas las interacciones pasan por un único listener global: cero aislamiento por feature
  • Sin inyección de dependencias; los servicios se importan directamente, sin abstracción
  • Sin sistema de módulos: las features crecen lado a lado sin límites claros

Por qué existe

Nacido de una frustración real.

Cada bot de Spacelaxy empezaba igual: un proyecto discord.js limpio que se convertía en un caos a medida que se añadían nuevas funcionalidades. Sin estructura, sin límites, estado global por todas partes. El código funcionaba, pero nadie quería tocarlo.

Spraxium empezó como una herramienta interna para resolver eso. Módulos, inyección de dependencias, guards: principios de backend aplicados al desarrollo de bots de Discord. Estuvo corriendo todos los bots de Spacelaxy en producción por más de un año antes de que nadie externo lo conociera.

Ahora es open source. El mismo framework, ordenado, documentado y listo para quienes están cansados de escribir los mismos if-else en cada listener.

Henry Thierry
Henry Thierry
Fundador, Spacelaxy • Creador de Spraxium

Slash commands

Define la estructura. Enfócate en la lógica. Mantenlas separadas.

Spraxium separa slash commands en dos archivos: una clase de comando que declara opciones y permisos, y un handler que recibe servicios inyectados y ejecuta la lógica. El framework los conecta automáticamente al arrancar.

  • Opciones type-safe con decorators @SlashOption
  • Inyección DI completa en el handler, como en cualquier otra clase
  • Guards aplicados a nivel de handler, no dentro del código
  • Auto-registrado en Discord durante la inicialización
src/modules/slash/commands/ban.command.ts
1import { SlashCommand, SlashOption } from '@spraxium/common';
2import { PermissionFlagsBits } from 'discord.js';
3
4@SlashCommand({
5 name: 'ban',
6 description: 'Ban a member from the server.',
7 defaultMemberPermissions: PermissionFlagsBits.BanMembers,
8})
9export class BanCommand {
10 @SlashOption.User('target', {
11 description: 'The member to ban',
12 required: true,
13 })
14 @SlashOption.String('reason', {
15 description: 'Reason for the ban',
16 required: false,
17 })
18 build() {}
19}

Ecosistema de paquetes

Un framework, doce paquetes.

Doce paquetes enfocados construidos sobre el mismo contrato de módulos y DI. Cada uno es opcional, versionado de forma independiente y entra en cualquier módulo con un solo import. Empieza con core y common. Suma el resto cuando tu bot crezca.

Componentes de UI

Construye componentes de UI de Discord como clases TypeScript.

Declara cada componente de UI de Discord como una clase TypeScript tipada. Sin constructores manuales ni opciones dispersas. Componible e inyectable por defecto.

Explorar Componentes
src/modules/moderation/schemas/buttons.ts
1import { Button, LinkButton } from '@spraxium/components';
2
3@Button({
4 customId: 'mod:ban-confirm',
5 label: 'Confirm Ban',
6 style: 'danger',
7 emoji: '🔨',
8})
9export class BanConfirmButton {}
10
11@Button({
12 customId: 'mod:ban-cancel',
13 label: 'Cancel',
14 style: 'secondary',
15})
16export class BanCancelButton {}
17
18@LinkButton({
19 label: 'View User',
20 url: 'https://discord.com/users/...',
21 emoji: '🔗',
22})
23export class ViewUserButton {}

Modales

Modales con experiencia nativa, validados y listos para producción.

Define campos de modal como propiedades de clase. Los validadores se ejecutan antes de invocar el handler. Las respuestas en caché sobreviven automáticamente al timeout de 15 minutos de Discord.

Ver documentación
1import {
2 ModalCache,
3 ModalComponent,
4 ModalInput,
5 ModalValidate,
6 minWords,
7 minLength,
8} from '@spraxium/components';
9
10@ModalCache({ ttl: 300 })
11@ModalComponent({ id: 'report', title: 'Report an issue' })
12export class ReportModal {
13 @ModalValidate([minWords(5)])
14 @ModalInput({
15 label: 'What happened?',
16 style: 'paragraph',
17 required: true,
18 maxLength: 1000,
19 })
20 description!: string;
21
22 @ModalValidate([minLength(3)])
23 @ModalInput({
24 label: 'Evidence link',
25 placeholder: 'https://…',
26 })
27 evidence!: string;
28}

Ecosistema CLI

Un comando. Cualquier integración.

La CLI de Spraxium no se limita a instalar dependencias. Genera providers, registra módulos y conecta configuraciones base en tu arquitectura en segundos. Haz clic en cualquier integración para ver el comando exacto y el setup generado.

Spraxium

Casos de uso

Un framework. Todo tipo de bot.

Desde bots con slash commands escalables hasta arquitecturas multi-servicio, cada paquete se integra de forma independiente y hace un solo trabajo bien hecho.

Arquitectura de bot escalable

Crea bots multi-módulo con DI topológica, pipelines de guards y lifecycle hooks tipados. @spraxium/core y @spraxium/common soportan estructuras que crecen de 10 a 200 comandos.

Endpoints HTTP dentro del bot

Ejecuta controllers REST en el mismo proceso que Discord. @spraxium/http ofrece DTOs, validación y un BotBridge para enviar mensajes en Discord directamente desde handlers HTTP.

Entrega de eventos entre servicios

Recibe eventos tipados y firmados con HMAC desde cualquier backend Node.js usando @spraxium/signal. Sin polling, sin base de datos compartida, sin acoplamiento entre servicios.

Jobs programados y automatización

Declara jobs cron e intervalos que arrancan tras onReady() y se detienen limpiamente al apagar. @spraxium/schedule se integra de forma nativa con el ciclo de vida de módulos.

Bots multilingües para comunidades

Resolución de idioma por servidor, archivos de mensajes cargados bajo demanda y claves de traducción tipadas en cada slash command. Impulsado por @spraxium/i18n.

Configuración tipada y observabilidad

Valida todas las variables de entorno al arrancar con esquemas autogenerados. Rastrea uso de comandos, latencia y tasas de error desde el primer día con @spraxium/env y @spraxium/analytics.

Opiniones reales de beta testers · pre-lanzamiento

“Ya probé discord.js, Necord e incluso REST puro. Nada se acerca. Spraxium es el primer framework que de verdad se siente diseñado para bots grandes. Necord se acopla demasiado a internals de discord.js y esa complejidad termina filtrándose por todo el proyecto. Con Spraxium, cada feature por fin tiene su lugar.”

Smoker's avatar
SmokerDesarrollador de bots · beta tester

Estado del Proyecto

Lo que está listo. Lo que viene.

Spraxium está en desarrollo activo. Aquí tienes una visión transparente de lo disponible hoy y de lo que está en roadmap.

Overall progress26 / 35
Completado
26
  • @spraxium/logger: structured logging
  • @spraxium/webhook: decorator-based senders
  • @Defer() and @AutoDefer() decorators
  • Process lock & --force-unlock flag
  • Upgrade notifier on startup
  • Cross-package stabilization (0.2.0)
  • Webhook handler decorators
  • Hot module reload (dev mode)
En progreso
3
  • Documentation site
  • Testing utilities & vitest helpers
  • Example bot projects
Próximamente
6
  • @spraxium/dashboard: web UI
  • Plugin registry & marketplace
  • Voice state handler decorators
  • CLI new project templates v2
  • Rate limiting decorators
  • @spraxium/cache: distributed cache

Empieza a construir

Trata tu bot como una superficie de producto.

Límites claros de módulos, un pipeline de guards que cubre todos los tipos de interacción, diagnósticos de arranque que muestran exactamente lo que se cargó y nueve paquetes listos para cuando tu bot necesite escalar.