O que é o Spraxium
Spraxium é um framework TypeScript construído sobre o Discord.js que entrega a camada de arquitetura que o Discord.js propositalmente não tenta resolver sozinho. O Discord.js cuida da comunicação de baixo nível com o gateway, incluindo WebSocket, REST, eventos crus e modelos de dados. O Spraxium entra a partir daí e organiza a aplicação com módulos, injeção de dependência, pipeline de guards, lifecycle hooks e uma sequência de boot determinística, para que o bot sempre suba do mesmo jeito.
Cada funcionalidade vive no próprio módulo, com fronteiras claras e dependências explícitas. O container de DI resolve e injeta tudo automaticamente: você declara o que cada classe precisa, e o framework faz a amarração.
Pré-requisitos
Antes de começar, você precisa de três coisas:
- Node.js 20 ou superior. O Spraxium acompanha as versões LTS atuais. Você pode conferir a versão instalada rodando
node -vno terminal, e tanto a LTS 20 quanto a LTS 22 são suportadas. - Um token de bot do Discord. Crie uma aplicação no Discord Developer Portal, adicione um Bot e copie o token. É ele que permite ao seu bot se autenticar no gateway do Discord.
- Um projeto TypeScript. O scaffold da CLI já monta o tsconfig.json com experimentalDecorators e emitDecoratorMetadata ativados, que são obrigatórios para o sistema de DI baseado em decorators usado pelo Spraxium.
Nunca exponha o token do bot
O token funciona como a senha do bot. Quem tiver acesso a ele consegue assumir o controle total da aplicação. Sempre deixe esse valor no .env e garanta que o .env esteja listado no .gitignore. O scaffold do Spraxium já adiciona essa proteção automaticamente.
Use um servidor de teste
Durante o desenvolvimento, a melhor prática é apontar o bot para um servidor privado seu. Assim você consegue registrar slash commands instantaneamente no escopo da guild e testar interações sem afetar usuários reais. Também vale a pena manter esse ambiente separado de qualquer servidor de produção para não misturar comandos, permissões ou rate limits.
Gerando o projeto
Use o comando de criação para gerar um projeto com a estrutura de pastas correta, configuração TypeScript pronta e dependências já instaladas. A CLI pergunta qual template você quer usar, qual package manager prefere e se deve inicializar um repositório Git.
npx @spraxium/cli@latest new my-botEstrutura inicial
Cada arquivo da base tem uma função arquitetural específica:
- main.ts: faz apenas o bootstrap; valida ambiente e sobe o framework
- app.env.ts: descreve o schema tipado das variáveis de ambiente antes da conexão com o Discord
- app.module.ts: raiz de composição; importa módulos de feature e não concentra regra de negócio
- modules/: uma pasta por domínio de funcionalidade
Bootstrap
O main.ts é o único arquivo que encosta diretamente na factory do framework. É ali que você valida variáveis de ambiente, cria a aplicação, carrega o grafo de módulos e abre a conexão com o Discord.
import { IntentPreset, SpraxiumFactory } from '@spraxium/core';
import { EnvValidator } from '@spraxium/env';
import { AppEnv } from './app.env';
import { AppModule } from './app.module';
async function main(): Promise<void> {
const env = EnvValidator.validate(AppEnv);
const app = await SpraxiumFactory.create({ token: env.token });
app.useModule(AppModule);
app.intents(IntentPreset.Standard);
await app.listen();
}
main();EnvValidator.validate lê o .env e valida cada campo contra o AppEnv. Se algum valor estiver ausente ou inválido, a execução falha imediatamente, antes mesmo do Discord conectar. Já o app.listen() resolve o grafo de DI, instancia providers, registra listeners e só depois faz login no gateway.
Módulo raiz
O AppModule é a raiz de composição. Ele importa módulos de feature, mas não deve concentrar providers nem listeners de negócio. Sempre que um novo domínio surgir no bot, o caminho natural é criar um módulo próprio e importá-lo aqui.
import { Module } from '@spraxium/common';
import { DefaultModule } from './modules/default/default.module';
@Module({
imports: [DefaultModule],
})
export class AppModule {}Regras centrais da arquitetura
Existem três regras que sustentam o funcionamento do framework:
- Um módulo por domínio de funcionalidade. Cada parte do bot, seja moderação, comandos, eventos ou integrações externas, deve ter o próprio módulo. Dependências entre áreas passam por imports e exports explícitos, não por estado global compartilhado.
- Injeção de dependência em tudo. Evite instanciar serviços manualmente com new. O ideal é declarar dependências no construtor e deixar o container resolver tudo. Isso reduz acoplamento, facilita teste com mocks e mantém o ciclo de vida sob controle do framework.
- Validação antes da conexão com o Discord. O grafo inteiro é resolvido antes do login. Se houver configuração inválida ou dependência faltando, o erro aparece no boot, com contexto claro, em vez de surgir só quando alguém usa um comando em produção.