jpskill.com
🛠️ 開発・MCP コミュニティ

code-simplification

動作を変えずにコードを整理し、可読性や保守性、拡張性を高めるために、複雑になった不要な部分を取り除き、よりシンプルで分かりやすいコードに改善するSkill。

📜 元の英語説明(参考)

Use when refactoring code for clarity without changing behavior. Use when code works but is harder to read, maintain, or extend than it should be. Use when reviewing code that has accumulated unnecessary complexity.

🇯🇵 日本人クリエイター向け解説

一言でいうと

動作を変えずにコードを整理し、可読性や保守性、拡張性を高めるために、複雑になった不要な部分を取り除き、よりシンプルで分かりやすいコードに改善するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o code-simplification.zip https://jpskill.com/download/9575.zip && unzip -o code-simplification.zip && rm code-simplification.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9575.zip -OutFile "$d\code-simplification.zip"; Expand-Archive "$d\code-simplification.zip" -DestinationPath $d -Force; ri "$d\code-simplification.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して code-simplification.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → code-simplification フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

コードの簡略化

Claude Code Simplifier plugin に触発されました。ここでは、あらゆる AI コーディングエージェント向けの、モデルに依存しない、プロセス駆動型のスキルとして適用されています。

概要

正確な動作を維持しながら、複雑さを軽減することでコードを簡略化します。目標は行数を減らすことではなく、読みやすく、理解しやすく、修正しやすく、デバッグしやすいコードにすることです。すべての簡略化は、簡単なテストに合格する必要があります。「新しいチームメンバーは、元のコードよりもこのコードをより早く理解できるか?」

いつ使用するか

  • 機能が動作し、テストに合格したが、実装が必要以上に重く感じられる場合
  • コードレビュー中に、可読性または複雑さの問題が指摘された場合
  • 深くネストされたロジック、長い関数、または不明確な名前が見つかった場合
  • 時間的制約の下で書かれたコードをリファクタリングする場合
  • ファイル全体に散在する関連ロジックを統合する場合
  • 重複または不整合を導入した変更をマージした後

使用しない場合:

  • コードがすでにクリーンで読みやすい場合 — 単に簡略化のためだけに簡略化しないでください
  • コードが何をするのかまだ理解していない場合 — 簡略化する前に理解してください
  • コードがパフォーマンスに重要な場合、および「より単純な」バージョンが測定可能なほど遅くなる場合
  • モジュール全体を書き換えようとしている場合 — 使い捨てのコードを簡略化するのは無駄な努力です

5つの原則

1. 動作を正確に維持する

コードが何をするかを決して変更しないでください — それをどのように表現するかだけを変更してください。すべての入力、出力、副作用、エラー動作、およびエッジケースは、同一のままでなければなりません。簡略化によって動作が維持されるかどうかわからない場合は、簡略化しないでください。

変更を加える前に必ず質問してください:
→ これはすべての入力に対して同じ出力を生成しますか?
→ これは同じエラー動作を維持しますか?
→ これは同じ副作用と順序を維持しますか?
→ 既存のすべてのテストは、修正なしで合格しますか?

2. プロジェクトの規約に従う

簡略化とは、外部の好みを押し付けるのではなく、コードベースとの一貫性を高めることを意味します。簡略化する前に:

1. CLAUDE.md / プロジェクトの規約を読む
2. 隣接するコードが同様のパターンをどのように処理するかを調べる
3. プロジェクトのスタイルに合わせる:
   - インポートの順序とモジュールシステム
   - 関数の宣言スタイル
   - 命名規則
   - エラー処理パターン
   - 型注釈の深さ

プロジェクトの一貫性を損なう簡略化は、簡略化ではありません — それは混乱です。

3. 明確さを巧妙さよりも優先する

コンパクトなバージョンを解析するために精神的な一時停止が必要な場合、明示的なコードはコンパクトなコードよりも優れています。

// 不明瞭: 密な三項演算子の連鎖
const label = isNew ? 'New' : isUpdated ? 'Updated' : isArchived ? 'Archived' : 'Active';

// 明確: 読みやすいマッピング
function getStatusLabel(item: Item): string {
  if (item.isNew) return 'New';
  if (item.isUpdated) return 'Updated';
  if (item.isArchived) return 'Archived';
  return 'Active';
}
// 不明瞭: インラインロジックを使用した連鎖的な reduce
const result = items.reduce((acc, item) => ({
  ...acc,
  [item.id]: { ...acc[item.id], count: (acc[item.id]?.count ?? 0) + 1 }
}), {});

// 明確: 名前付きの中間ステップ
const countById = new Map<string, number>();
for (const item of items) {
  countById.set(item.id, (countById.get(item.id) ?? 0) + 1);
}

4. バランスを維持する

簡略化には失敗モードがあります: 過度の簡略化です。次の落とし穴に注意してください。

  • 過度に積極的なインライン化 — 概念に名前を付けたヘルパーを削除すると、呼び出し元が読みにくくなります
  • 無関係なロジックの結合 — 2つの単純な関数を1つの複雑な関数にマージしても、単純化にはなりません
  • 「不要な」抽象化の削除 — 一部の抽象化は、複雑さではなく、拡張性またはテスト容易性のために存在します
  • 行数の最適化 — 行数を減らすことが目標ではありません。理解しやすさが目標です

5. 変更された範囲に限定する

デフォルトでは、最近変更されたコードを簡略化します。スコープを広げるように明示的に指示されない限り、無関係なコードのドライブバイリファクタリングは避けてください。スコープ外の簡略化は、diff にノイズを作成し、意図しない回帰のリスクがあります。

簡略化プロセス

ステップ 1: 触る前に理解する

コードを読みます。コードが何をするのか、なぜ存在するのか、そしてそれがより大きなシステムにどのように適合するかを理解します。

簡略化する前に、以下に答えてください:
- このコードの責任は何ですか?
- 何がそれを呼び出しますか?それは何を呼び出しますか?
- エッジケースとエラーパスは何ですか?
- 予想される動作を定義するテストはありますか?
- なぜこのように書かれたのでしょうか? (パフォーマンス?プラットフォームの制約?歴史的な理由?)

これらに答えられない場合は、簡略化する準備ができていません。まず、より多くのコンテキストを読んでください。

ステップ 2: 簡略化の機会を特定する

次のパターンをスキャンします — それぞれが具体的なシグナルであり、曖昧な臭いではありません。

構造的な複雑さ:

パターン シグナル 簡略化
深いネスト (3+ レベル) 制御フローを追跡するのが難しい 条件をガード句またはヘルパー関数に抽出する
長い関数 (50+ 行) 複数の責任 説明的な名前を持つ、焦点を絞った関数に分割する
ネストされた三項演算子 解析するためにメンタルスタックが必要 if/else チェーン、switch、またはルックアップオブジェクトに置き換える
ブールパラメータフラグ doThing(true, false, true) オプションオブジェクトまたは個別の関数に置き換える
繰り返される条件 複数の場所で同じ if チェック 名前が適切に付けられた述語関数に抽出する

命名と可読性:

パターン シグナル 簡略化
汎用的な名前 dataresulttempvalitem コンテンツを説明するように名前を変更する: userProfilevalidationErrors
省略された名前 usrcfgbtnevt 省略形が普遍的でない限り、完全な単語を使用する (idurlapi)
誤解を招く名前 状態も変更する get という名前の関数 実際の動作を反映するように名前を変更する
「何」を説明するコメント count++ の上の // increment counter コメントを削除する — コードは十分に明確です
コメント expl

(原文はここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Code Simplification

Inspired by the Claude Code Simplifier plugin. Adapted here as a model-agnostic, process-driven skill for any AI coding agent.

Overview

Simplify code by reducing complexity while preserving exact behavior. The goal is not fewer lines — it's code that is easier to read, understand, modify, and debug. Every simplification must pass a simple test: "Would a new team member understand this faster than the original?"

When to Use

  • After a feature is working and tests pass, but the implementation feels heavier than it needs to be
  • During code review when readability or complexity issues are flagged
  • When you encounter deeply nested logic, long functions, or unclear names
  • When refactoring code written under time pressure
  • When consolidating related logic scattered across files
  • After merging changes that introduced duplication or inconsistency

When NOT to use:

  • Code is already clean and readable — don't simplify for the sake of it
  • You don't understand what the code does yet — comprehend before you simplify
  • The code is performance-critical and the "simpler" version would be measurably slower
  • You're about to rewrite the module entirely — simplifying throwaway code wastes effort

The Five Principles

1. Preserve Behavior Exactly

Never change what the code does — only how it expresses it. All inputs, outputs, side effects, error behavior, and edge cases must remain identical. If you're not sure a simplification preserves behavior, don't make it.

ASK BEFORE EVERY CHANGE:
→ Does this produce the same output for every input?
→ Does this maintain the same error behavior?
→ Does this preserve the same side effects and ordering?
→ Do all existing tests still pass without modification?

2. Follow Project Conventions

Simplification means making code more consistent with the codebase, not imposing external preferences. Before simplifying:

1. Read CLAUDE.md / project conventions
2. Study how neighboring code handles similar patterns
3. Match the project's style for:
   - Import ordering and module system
   - Function declaration style
   - Naming conventions
   - Error handling patterns
   - Type annotation depth

Simplification that breaks project consistency is not simplification — it's churn.

3. Prefer Clarity Over Cleverness

Explicit code is better than compact code when the compact version requires a mental pause to parse.

// UNCLEAR: Dense ternary chain
const label = isNew ? 'New' : isUpdated ? 'Updated' : isArchived ? 'Archived' : 'Active';

// CLEAR: Readable mapping
function getStatusLabel(item: Item): string {
  if (item.isNew) return 'New';
  if (item.isUpdated) return 'Updated';
  if (item.isArchived) return 'Archived';
  return 'Active';
}
// UNCLEAR: Chained reduces with inline logic
const result = items.reduce((acc, item) => ({
  ...acc,
  [item.id]: { ...acc[item.id], count: (acc[item.id]?.count ?? 0) + 1 }
}), {});

// CLEAR: Named intermediate step
const countById = new Map<string, number>();
for (const item of items) {
  countById.set(item.id, (countById.get(item.id) ?? 0) + 1);
}

4. Maintain Balance

Simplification has a failure mode: over-simplification. Watch for these traps:

  • Inlining too aggressively — removing a helper that gave a concept a name makes the call site harder to read
  • Combining unrelated logic — two simple functions merged into one complex function is not simpler
  • Removing "unnecessary" abstraction — some abstractions exist for extensibility or testability, not complexity
  • Optimizing for line count — fewer lines is not the goal; easier comprehension is

5. Scope to What Changed

Default to simplifying recently modified code. Avoid drive-by refactors of unrelated code unless explicitly asked to broaden scope. Unscoped simplification creates noise in diffs and risks unintended regressions.

The Simplification Process

Step 1: Understand Before Touching

Read the code. Understand what it does, why it exists, and how it fits into the larger system.

BEFORE SIMPLIFYING, ANSWER:
- What is this code's responsibility?
- What calls it? What does it call?
- What are the edge cases and error paths?
- Are there tests that define the expected behavior?
- Why might it have been written this way? (Performance? Platform constraint? Historical reason?)

If you can't answer these, you're not ready to simplify. Read more context first.

Step 2: Identify Simplification Opportunities

Scan for these patterns — each one is a concrete signal, not a vague smell:

Structural complexity:

Pattern Signal Simplification
Deep nesting (3+ levels) Hard to follow control flow Extract conditions into guard clauses or helper functions
Long functions (50+ lines) Multiple responsibilities Split into focused functions with descriptive names
Nested ternaries Requires mental stack to parse Replace with if/else chains, switch, or lookup objects
Boolean parameter flags doThing(true, false, true) Replace with options objects or separate functions
Repeated conditionals Same if check in multiple places Extract to a well-named predicate function

Naming and readability:

Pattern Signal Simplification
Generic names data, result, temp, val, item Rename to describe the content: userProfile, validationErrors
Abbreviated names usr, cfg, btn, evt Use full words unless the abbreviation is universal (id, url, api)
Misleading names Function named get that also mutates state Rename to reflect actual behavior
Comments explaining "what" // increment counter above count++ Delete the comment — the code is clear enough
Comments explaining "why" // Retry because the API is flaky under load Keep these — they carry intent the code can't express

Redundancy:

Pattern Signal Simplification
Duplicated logic Same 5+ lines in multiple places Extract to a shared function
Dead code Unreachable branches, unused variables, commented-out blocks Remove (after confirming it's truly dead)
Unnecessary abstractions Wrapper that adds no value Inline the wrapper, call the underlying function directly
Over-engineered patterns Factory-for-a-factory, strategy-with-one-strategy Replace with the simple direct approach
Redundant type assertions Casting to a type that's already inferred Remove the assertion

Step 3: Apply Changes Incrementally

Make one simplification at a time. Run tests after each change.

FOR EACH SIMPLIFICATION:
1. Make the change
2. Run the test suite
3. If tests pass → commit (or continue to next simplification)
4. If tests fail → revert and reconsider

Never batch multiple simplifications into a single untested change. If something breaks, you need to know which simplification caused it.

Step 4: Verify the Result

After all simplifications, step back and evaluate the whole:

COMPARE BEFORE AND AFTER:
- Is the simplified version genuinely easier to understand?
- Did you introduce any new patterns inconsistent with the codebase?
- Is the diff clean and reviewable?
- Would a teammate approve this change?

If the "simplified" version is harder to understand or review, revert. Not every simplification attempt succeeds.

Language-Specific Guidance

TypeScript / JavaScript

// SIMPLIFY: Unnecessary async wrapper
// Before
async function getUser(id: string): Promise<User> {
  return await userService.findById(id);
}
// After
function getUser(id: string): Promise<User> {
  return userService.findById(id);
}

// SIMPLIFY: Verbose conditional assignment
// Before
let displayName: string;
if (user.nickname) {
  displayName = user.nickname;
} else {
  displayName = user.fullName;
}
// After
const displayName = user.nickname || user.fullName;

// SIMPLIFY: Manual array building
// Before
const activeUsers: User[] = [];
for (const user of users) {
  if (user.isActive) {
    activeUsers.push(user);
  }
}
// After
const activeUsers = users.filter((user) => user.isActive);

// SIMPLIFY: Redundant boolean return
// Before
function isValid(input: string): boolean {
  if (input.length > 0 && input.length < 100) {
    return true;
  }
  return false;
}
// After
function isValid(input: string): boolean {
  return input.length > 0 && input.length < 100;
}

Python

# SIMPLIFY: Verbose dictionary building
# Before
result = {}
for item in items:
    result[item.id] = item.name
# After
result = {item.id: item.name for item in items}

# SIMPLIFY: Nested conditionals with early return
# Before
def process(data):
    if data is not None:
        if data.is_valid():
            if data.has_permission():
                return do_work(data)
            else:
                raise PermissionError("No permission")
        else:
            raise ValueError("Invalid data")
    else:
        raise TypeError("Data is None")
# After
def process(data):
    if data is None:
        raise TypeError("Data is None")
    if not data.is_valid():
        raise ValueError("Invalid data")
    if not data.has_permission():
        raise PermissionError("No permission")
    return do_work(data)

React / JSX

// SIMPLIFY: Verbose conditional rendering
// Before
function UserBadge({ user }: Props) {
  if (user.isAdmin) {
    return <Badge variant="admin">Admin</Badge>;
  } else {
    return <Badge variant="default">User</Badge>;
  }
}
// After
function UserBadge({ user }: Props) {
  const variant = user.isAdmin ? 'admin' : 'default';
  const label = user.isAdmin ? 'Admin' : 'User';
  return <Badge variant={variant}>{label}</Badge>;
}

// SIMPLIFY: Prop drilling through intermediate components
// Before — consider whether context or composition solves this better.
// This is a judgment call — flag it, don't auto-refactor.

Common Rationalizations

Rationalization Reality
"It's working, no need to touch it" Working code that's hard to read will be hard to fix when it breaks. Simplifying now saves time on every future change.
"Fewer lines is always simpler" A 1-line nested ternary is not simpler than a 5-line if/else. Simplicity is about comprehension speed, not line count.
"I'll just quickly simplify this unrelated code too" Unscoped simplification creates noisy diffs and risks regressions in code you didn't intend to change. Stay focused.
"The types make it self-documenting" Types document structure, not intent. A well-named function explains why better than a type signature explains what.
"This abstraction might be useful later" Don't preserve speculative abstractions. If it's not used now, it's complexity without value. Remove it and re-add when needed.
"The original author must have had a reason" Maybe. Check git blame. But accumulated complexity often has no reason — it's just the residue of iteration under pressure.

Red Flags

  • Simplification that requires modifying tests to pass (you likely changed behavior)
  • "Simplified" code that is longer and harder to follow than the original
  • Renaming things to match your preferences rather than project conventions
  • Removing error handling because "it makes the code cleaner"
  • Simplifying code you don't fully understand
  • Batching many simplifications into one large, hard-to-review commit
  • Refactoring code outside the scope of the current task without being asked

Verification

After completing a simplification pass:

  • [ ] All existing tests pass without modification
  • [ ] Build succeeds with no new warnings
  • [ ] Linter/formatter passes (no style regressions)
  • [ ] Each simplification is a reviewable, incremental change
  • [ ] The diff is clean — no unrelated changes mixed in
  • [ ] Simplified code follows project conventions (checked against CLAUDE.md or equivalent)
  • [ ] No error handling was removed or weakened
  • [ ] No dead code was left behind (unused imports, unreachable branches)
  • [ ] A teammate or review agent would approve the change as a net improvement