kythia-core
v1.1.0
Published
Core library for the Kythia main Discord bot: extensible, modular, and scalable foundation for commands, components, and event management.
Downloads
743
Maintainers
Readme
📚 Documentation
This README provides a quick overview and getting started guide. For comprehensive documentation:
| Doc | Contents |
|---|---|
| ARCHITECTURE.md | System architecture, design patterns, data flow diagrams |
| CONTAINER.md | KythiaContainer — every property, availability timeline, usage patterns |
| CONFIG.md | Full kythia.config.js field reference |
| ADDON_GUIDE.md | Step-by-step guide to creating addons (commands, events, DB, i18n) |
| CLASS_REFERENCE.md | Full class and method API documentation |
| CLI_REFERENCE.md | CLI tools: migrate, make:model, lang:check, etc. |
| METRICS.md | Prometheus metrics and Grafana query examples |
🌟 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 in your project root:
// kythia.config.js
require('@dotenvx/dotenvx').config();
module.exports = {
env: process.env.NODE_ENV || 'production', // 'development' | 'production'
licenseKey: process.env.LICENSE_KEY,
legal: {
acceptTOS: true, // Required — must be true
dataCollection: true, // Required — must be true
},
version: '1.0.0',
bot: {
name: 'MyBot',
token: process.env.DISCORD_TOKEN,
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
totalShards: 'auto',
mainGuildId: process.env.MAIN_GUILD_ID,
devGuildId: process.env.DEV_GUILD_ID,
color: '#5865F2',
prefixes: ['!'],
status: 'online',
activityType: 3, // 3 = Watching
activity: 'the server',
globalCommandCooldown: 3000,
language: 'en',
locale: 'en-US',
timezone: 'UTC',
},
db: {
driver: 'sqlite', // 'sqlite' | 'mysql' | 'postgres'
name: 'kythiadata.sqlite',
timezone: '+00:00',
redis: process.env.REDIS_URL,
redisCacheVersion: 'v1',
},
owner: {
ids: process.env.OWNER_IDS,
names: 'YourName',
},
sentry: {
dsn: process.env.SENTRY_DSN,
},
addons: {
core: { active: true },
economy: { active: true },
},
};See CONFIG.md for the complete field reference including MySQL/PostgreSQL, Redis, all addon configs, and antispam settings.
🔌 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 ADDON_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
- KythiaContainer Reference — Every service, model, and helper available in the DI container
- Configuration Reference — Every kythia.config.js field with types and examples
- Addon Authoring Guide — Commands, events, DB, i18n, tasks from scratch
- Addon Architecture — Dependency resolution and load order
- Metrics & Monitoring — Prometheus metrics and Grafana setup
- Obfuscation — Code obfuscation configuration
🤝 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.
🔗 Links
- Architecture
- Container Reference
- Config Reference
- Addon Guide
- Class Reference
- CLI Reference
- Metrics
- GitHub Issues
- Discord Server
