kythia-core
v0.13.0-beta
Published
Core library for the Kythia main Discord bot: extensible, modular, and scalable foundation for commands, components, and event management.
Maintainers
Readme
📚 Documentation
This README provides a quick overview and getting started guide. For comprehensive documentation:
- ARCHITECTURE.md - Complete system architecture, design patterns, and data flow
- CLASS_REFERENCE.md - Full class and method documentation
- DEV_GUIDE.md - Development guide, best practices, and patterns
- CLI_REFERENCE.md - CLI tools and commands reference
- METRICS.md - Performance metrics and monitoring guide
🌟 What is Kythia Core?
Kythia Core is a powerful, production-ready framework for building scalable Discord bots. Built on top of discord.js v14, it provides a complete ecosystem for bot development with:
- 🔌 Addon System - Modular architecture with hot-loadable addons
- 🗄️ Advanced ORM - Hybrid Redis/LRU caching with automatic invalidation
- 🔄 Migration System - Laravel-style migrations with batch support
- 🎯 Smart Routing - Automatic command, event, and component registration
- 🛡️ Middleware - Flexible permission, cooldown, and validation system
- 📦 Dependency Injection - Clean, testable architecture with DI container
- 🔧 CLI Tools - Powerful development tools for scaffolding and management
- 📊 Telemetry - Built-in monitoring with Sentry integration
- 🌐 i18n - Complete localization system with auto-translation
- ⏰ Task Scheduler - Cron and interval-based task system
🏗️ Core Architecture
┌─────────────────────────────────────────────────────────────┐
│ Kythia Core │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Addon │ │ Interaction │ │ Event │ │
│ │ Manager │ │ Manager │ │ Manager │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Translator │ │ Shutdown │ │ Telemetry │ │
│ │ Manager │ │ Manager │ │ Manager │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Database Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Kythia │ │ Kythia │ │ Kythia │ │
│ │ Model │ │ Migrator │ │ Sequelize │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Caching Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Redis (Primary) ↔ LRU Map (Fallback) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘See ARCHITECTURE.md for detailed system design.
🚀 Quick Start
Installation
npm install kythia-core discord.js
# or
yarn add kythia-core discord.js
# or
pnpm add kythia-core discord.jsBasic Setup
// index.js
// index.js
const { Client, GatewayIntentBits } = require('discord.js');
const { Kythia, KythiaModel, createSequelizeInstance } = require('kythia-core');
const config = require('./kythia.config.js');
// 1. Setup Client
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers,
],
});
// 2. Setup dependencies
const logger = require('./core/helpers/logger');
const translator = require('./core/helpers/translator');
const Redis = require('ioredis');
const redis = new Redis(config.db.redis, { lazyConnect: true });
// 3. Create Sequelize instance
const sequelize = createSequelizeInstance(config, logger);
// 4. Inject dependencies into KythiaModel
KythiaModel.setDependencies({ logger, config, redis });
// 5. Create dependency container
const dependencies = {
client,
config,
logger,
translator,
redis,
sequelize,
models: {},
helpers: {
// Your addon helpers
},
appRoot: __dirname,
};
// 6. Initialize and start
const kythia = new Kythia(dependencies);
await kythia.start();Sharding (Optional)
For large bots, use the built-in ShardingManager to spawn shards easily.
Create a new entry file (e.g., sharding.js):
// sharding.js
const { ShardingManager } = require('kythia-core');
require('dotenv').config();
const manager = new ShardingManager({
scriptPath: 'dist/index.js', // Path to your compiled bot entry file
token: process.env.DISCORD_TOKEN,
totalShards: 'auto',
});
await manager.spawn();The ShardingManager includes built-in production protections:
- Crash loop detection — if a shard dies ≥ 3 times within 5 minutes, spawning is paused for 2 minutes before retrying
- OOM kill detection — exit code 137 / SIGKILL triggers a distinct alert log with actionable advice
- Lifetime restart tracking —
manager.getShardRestartCount(shardId)andmanager.getShardStats()expose per-shard restart history
Project Structure
kythia-bot/
├── addons/
│ ├── core/ # Core addon
│ │ ├── addon.json # Addon metadata
│ │ ├── commands/ # Slash commands
│ │ ├── events/ # Discord events
│ │ ├── buttons/ # Button handlers
│ │ ├── modals/ # Modal handlers
│ │ ├── select_menus/ # Select menu handlers
│ │ ├── tasks/ # Scheduled tasks
│ │ ├── database/
│ │ │ ├── models/ # Sequelize models
│ │ │ └── migrations/ # Database migrations
│ │ └── register.js # Addon initialization
│ └── feature/ # Feature addon
│ └── ...
├── kythia.config.js # Bot configuration
├── package.json
└── index.js # Entry point⚙️ Configuration
Create kythia.config.js:
module.exports = {
bot: {
token: process.env.DISCORD_TOKEN,
clientId: process.env.CLIENT_ID,
testGuildId: process.env.TEST_GUILD_ID,
},
db: {
mysql: {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
database: process.env.DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASS,
},
redis: {
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
},
},
addons: {
// Addon configuration
core: { active: true, priority: 0 },
feature: { active: true, priority: 50 },
},
};🔌 Creating Your First Addon
1. Create addon structure
npx kythia make:addon --name myfeature2. Define addon metadata
// addons/myfeature/addon.json
{
"name": "myfeature",
"version": "1.0.0",
"priority": 50,
"dependencies": ["core"]
}3. Create a command
// addons/myfeature/commands/hello.js
const { SlashCommandBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('hello')
.setDescription('Say hello!'),
async execute(interaction) {
const { logger } = interaction.client.container;
logger.info('Hello command executed!');
await interaction.reply('Hello, World!');
}
};4. Create a scheduled task
// addons/myfeature/tasks/daily-report.js
module.exports = {
schedule: '0 0 * * *', // Daily at midnight
async execute(container) {
const { logger } = container;
logger.info('Running daily report...');
}
};See DEV_GUIDE.md for complete addon development guide.
🗄️ Database & Models
Creating a Model
npx kythia make:model --name User --addon myfeature// addons/myfeature/database/models/User.js
const { KythiaModel } = require('kythia-core');
const { DataTypes } = require('sequelize');
class User extends KythiaModel {
static tableName = 'users';
static init(sequelize) {
return super.init({
userId: {
type: DataTypes.STRING,
unique: true,
},
username: DataTypes.STRING,
points: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
}, {
sequelize,
modelName: 'User',
tableName: this.tableName,
});
}
}
module.exports = User;Using the Model with Cache
// In your command
const { models } = interaction.client.container;
const { User } = models;
// Get with cache (auto Redis/LRU)
const user = await User.getCache({
where: { userId: interaction.user.id }
});
// Create with cache invalidation
const newUser = await User.create({
userId: interaction.user.id,
username: interaction.user.username,
});Creating Migrations
npx kythia make:migration --name create_users_table --addon myfeature// addons/myfeature/database/migrations/20250128000000_create_users_table.js
module.exports = {
up: async (queryInterface, DataTypes) => {
await queryInterface.createTable('users', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
userId: {
type: DataTypes.STRING,
unique: true,
},
points: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE,
});
},
down: async (queryInterface) => {
await queryInterface.dropTable('users');
}
};Run migrations:
npx kythia migrate🛠️ CLI Tools
Kythia Core includes powerful CLI tools:
# Database
npx kythia migrate # Run migrations
npx kythia migrate --fresh # Fresh migration
npx kythia migrate --rollback # Rollback last batch
npx kythia make:migration # Create migration
npx kythia make:model # Create model
npx kythia cache:clear # Clear Redis cache
# Localization
npx kythia lang:check # Check translation keys
npx kythia lang:translate --target ja # Auto-translate
# Development
npx kythia dev:namespace # Add JSDoc headers
npx kythia gen:structure # Generate project tree
npx kythia version:up # Sync version tagsSee CLI_REFERENCE.md for complete command reference.
🎯 Key Features
Addon Dependency Management
{
"name": "analytics",
"priority": 50,
"dependencies": ["core", "database"]
}Addons are loaded in dependency order with automatic validation.
Task Scheduling
// Cron-based
module.exports = {
schedule: '*/5 * * * *', // Every 5 minutes
execute: async (container) => { /* ... */ }
};
// Interval-based
module.exports = {
schedule: 60000, // Every 60 seconds
execute: async (container) => { /* ... */ }
};Middleware System
const { botPermissions } = require('kythia-core/middlewares');
module.exports = {
data: /* ... */,
middlewares: [
botPermissions(['SendMessages', 'EmbedLinks']),
],
execute: async (interaction) => { /* ... */ }
};Hybrid Caching
Automatic Redis + LRU fallback with tag-based invalidation:
// Automatically uses Redis if available, falls back to LRU
const user = await User.getCache({ where: { id: 1 } });
// Automatic cache invalidation on updates
await user.update({ points: 100 }); // Cache auto-cleared📖 Advanced Topics
- Dependency Injection Pattern - Avoiding circular dependencies
- Migration Best Practices - Safe schema management
- Cache Strategies - Optimizing performance
- Addon Architecture - Building scalable addons
- Testing Guide - Writing tests for your bot
- Deployment - Production deployment guide
🤝 Contributing
We welcome contributions! Please see our contributing guidelines.
📜 License
This project is licensed under the CC BY NC 4.0 License - see the LICENSE file for details.
