メインコンテンツまでスキップ

CC / CHACCHANv2.0.0 · npm 公開中

置くだけで、
動く。

クラスを置く。フレームワークが見つけ、登録し、つなぐ。
Discord Bot の起動までを、規約と型に任せられます。

bun add @cc-discord-framework/core

auto-discovery — 登録コードを書かずに、配置だけで Bot が組み上がる

Project status / Updated 2026-08-25

いま選ぶ版と、頼れる場所。

公開中の v2(@cc-discord-framework/core)と旧 npm パッケージ v1 を混同しないための、現在地をまとめました。
詳しい状況とサポート方針 →

Docs target / npm 公開中 · 2026-08-25

v2 — @cc-discord-framework/core

このサイトと main のコードが説明する現行版。公式プラグインも 同じ @cc-discord-framework スコープで公開されています。

bun add @cc-discord-framework/core導入手順を確認する →

旧パッケージ / legacy · 2026-05-10

v1.0.5 — 旧 cc-discord-framework

スコープなしの旧パッケージは旧世代の 1.x です。v2 とは API 互換ではないため、新規導入では使わないでください。

npm の v1 を確認する ↗v1.0.5 Release ↗
CC の耳を持つ熊。CC は CHACCHAN から

Maintained by

CHACCHAN

熊の耳にした2つの C は CHACCHAN から。CHACCHAN が設計・実装・ ドキュメントを保守する個人メンテナンスの OSS です。公開コードと 運用リファレンス Bot を基準に改善しています。

GitHub プロフィール ↗

01 — 設計思想

書くのは Bot の機能だけ。配線はフレームワークの仕事。

発見・登録・ルーティング・型付け — Bot を書くたびに繰り返してきた「いつもの配線」を、規約と型で肩代わりします。

規約が構造になる

commands/ に置いたクラスが、そのままスラッシュコマンドになる。 import も登録リストも書きません。名前はクラス名から導出 (UserInfoCommand/user-info)。

サービスは this に収束

どのコンポーネントからも this.services.audio / this.services.ai / this.services.ui。 宣言マージで型も通ります — 手動のジェネリクス指定はありません。

discord.js のまま

export * from "discord.js" — 全 API を再エクスポートし、Client は discord.js の Client そのもの。 これまでの知識も、エコシステムも、すべてそのまま使えます。

02 — discord.js との関係

discord.js を、置き換えない。

cc-discord-framework は discord.js 14 の全 API を再エクスポートします (export * from "discord.js")。 柔軟性はそのままに、その上へ規約と型の構造を足す — 同じ discord.js でも、 書く量はこれだけ変わります。

discord.js のみ定義・登録・ルーティングを手で配線

index.ts手動
import {
Client,
GatewayIntentBits,
REST,
Routes,
SlashCommandBuilder,
} from "discord.js";

// 1) コマンド定義を組み立てて…
const commands = [
new SlashCommandBuilder()
.setName("ping")
.setDescription("Botの応答速度を確認します。"),
// コマンドを足すたびにここへ追記
];

// 2) REST API で自分で登録して…
const rest = new REST().setToken(process.env.DISCORD_TOKEN!);
await rest.put(Routes.applicationCommands(process.env.APP_ID!), {
body: commands.map((c) => c.toJSON()),
});

// 3) ルーティングも自分で書く
const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.on("interactionCreate", async (interaction) => {
if (!interaction.isChatInputCommand()) return;
switch (interaction.commandName) {
case "ping":
await interaction.reply(`Pong! ${client.ws.ping}ms`);
break;
// コマンドを足すたびに分岐も追記
}
});

await client.login(process.env.DISCORD_TOKEN);

cc-discord-frameworkファイルを置くことが、そのまま登録

src/index.ts自動
// src/index.ts — エントリポイントはこれだけ
import { Client, GatewayIntentBits } from "@cc-discord-framework/core";

const client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(); // トークンは DISCORD_TOKEN 環境変数から自動使用
src/commands/PingCommand.ts自動
// src/commands/PingCommand.ts — 置くだけ。登録・同期は自動
import { Command, type ChatInputCommandInteraction } from "@cc-discord-framework/core";

@Command.define({ description: "Botの応答速度を確認します。" })
export class PingCommand extends Command {
override async chatInputRun(interaction: ChatInputCommandInteraction) {
await interaction.reply(`Pong! ${this.client.ws.ping}ms`);
}
}

interaction は discord.js の型そのもの。2つ目のコマンドは ファイルをもう1枚置くだけで、左のコードのように登録行や分岐が増えることはありません。

03 — 主要機能

小さなコアと、本物の拡張点。

コアが持つのはサービス・コマンド・リスナー・Precondition だけ。それ以外は、同じ仕組みの上にプラグインとして積み上がります。

01

標準デコレータ(TC39)

@Command.define({...}) は TC39 標準デコレータのみ。 experimentalDecorators も reflect-metadata も不要です。 デコレータは宣言し、ローダーが実行する — 厳密に分離されています。

02

設定は config/ に分割

createClient()src/config/ を読み、1関心1ファイルの 設定を合成。plugins は priority 順に連結、intents は 合併(union)されます。

03

プラグインは「種別」を足す

プラグインは機能ではなくコンポーネント種別ごと追加できます。utils は tasks/、music は resolvers/+providers/、 ai は ai/ — すべて Public API だけで実現。

04

すべて差し替え可能

ユーザーに見える文言・色・上限は、すべてただの既定値。 変更できないハードコードは設計ルールとして存在しません。 Bot の見せ方は Bot が決めます。

05

Bun ファースト

Bun 1.4+ 専用。TypeScript をそのまま実行するので、開発にビルド工程は ありません。500件を超える自動テストを bun test でまとめて実行できます。

06

型はマージで効く

リスナーのイベント引数、ストア参照、this.services.*、 Precondition 名 — 宣言マージにより、手動のジェネリクス指定なしで型が通ります。

04 — コード

実際の Bot から、そのまま。

以下はすべて、リポジトリ同梱の公式リファレンス Bot(client/)で実際に動いているコードです。

コマンド本体は、1呼び出し。

オプションはデコレータで宣言し、本体は this.services.ai.reply() の1行。defer・ストリーミング表示・ 長文の分割・失敗時の表示は、すべてサービス側の責務です。

  • コマンド名はクラス名から自動導出(AskCommand/ask)
  • Discord への登録・同期も ready 時に自動
src/commands/ai/AskCommand.ts
import {
ApplicationCommandOptionType,
Command,
type ChatInputCommandInteraction,
} from "@cc-discord-framework/core";

@Command.define({
description: "AIに質問します(会話履歴は使いません)。",
options: [
{
type: ApplicationCommandOptionType.String,
name: "prompt",
description: "聞きたいこと",
required: true,
},
],
})
export class AskCommand extends Command {
override async chatInputRun(interaction: ChatInputCommandInteraction) {
// defer・ストリーミング表示・長文の分割・失敗時の表示は reply() の担当。
await this.services.ai.reply(interaction, {
prompt: interaction.options.getString("prompt", true),
});
}
}

05 — プラグイン

プラグインは、機能ではなく「種別」を足す。

プラグインが提供するのは、コンポーネント種別の自動ロード・サービス・ イベントの3つだけ。コマンドは登録しません /play/ask も Bot の機能なので、src/commands/ に自分で書きます。文言も見せ方も、Bot が決める。

そして種別は横断して合成できます。src/ai/ のツールの中で this.services.audio が普通に動く — 「いま流れている曲」を AI が答えられるのは、この合成のおかげです。

独自のデコレータ・ディレクトリ・ライフサイクルを持つ新しい種別を、 Public API だけで丸ごと追加できます。公式プラグインも、 この同じ拡張点の上に立っています。

  • src/
  • index.tsエントリポイント(自動探索のルート)
  • config/設定 — 1関心1ファイル
  • commands/Commandコア
  • listeners/Listenerコア
  • preconditions/Preconditionコア
  • services/Serviceコア
  • tasks/Task — 定期実行utils
  • resolvers/ providers/音源の解決と再生music
  • ai/AiTool — LLM から呼べる関数ai

置く場所が、そのまま役割。プラグインを入れると、読めるディレクトリが増える。

06 — 公式プラグイン

重い依存は、コアに持ち込まない。

公式プラグインはそれぞれ独立したパッケージ。すべて npm の @cc-discord-framework スコープで公開されていて、使う分だけ bun add で足せます。

07 — はじめる

まず、1枚置いてみる。

最小の Bot まで3ステップ。ボイラープレートの生成も、ビルドの設定もありません。

  1. 1

    インストール

    discord.js は同梱・再エクスポートされるので、個別にインストールする 必要はありません。ランタイムは Bun 1.4+ だけ。

  2. 2

    エントリポイントを書く

    src/index.tsClient を作って login()。トークンは DISCORD_TOKEN 環境変数から自動で使われます。

  3. 3

    クラスを置く

    src/commands/ にコマンドのクラスを1枚。ビルド工程なしで bun run src/index.ts — もう /ping が動いています。

terminal
bun add @cc-discord-framework/core
bun run src/index.ts

Built in Japan

cc-discord-framework は日本発のオープンソースです。 ドキュメントもコードコメントもエラーメッセージも、翻訳ではなく 最初から日本語で書かれています。MIT License。