# Code Simplification > Simplifica código para mejorar su claridad sin cambiar su comportamiento, útil al refactorizar o revisar código que acumuló complejidad innecesaria. Fuente: https://skillsagentes.com/skills/addyosmani/agent-skills/code-simplification Markdown: https://skillsagentes.com/skills/addyosmani/agent-skills/code-simplification.md Repositorio: https://github.com/addyosmani/agent-skills Autor: addyosmani Licencia: MIT Actualizado: hace 4 meses Coste de contexto: 61 tok instalada, 3.4k tok al activarse, 3.4k tok con todos los archivos del bundle Bundle: 1 archivo, 13 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add addyosmani/agent-skills --skill code-simplification --agent claude-code # Cursor npx -y skills add addyosmani/agent-skills --skill code-simplification --agent cursor # Codex npx -y skills add addyosmani/agent-skills --skill code-simplification --agent codex # Gemini CLI npx -y skills add addyosmani/agent-skills --skill code-simplification --agent gemini # Windsurf npx -y skills add addyosmani/agent-skills --skill code-simplification --agent windsurf # Cline npx -y skills add addyosmani/agent-skills --skill code-simplification --agent cline ``` ## Qué hace - Guía la refactorización de código para reducir complejidad sin alterar el comportamiento - Aplica un proceso paso a paso: entender antes de tocar, identificar patrones, simplificar de forma incremental y verificar - Detecta patrones concretos como anidamiento profundo, funciones largas, ternarios anidados y nombres genéricos - Recomienda mantener los cambios de simplificación separados de los de nuevas funcionalidades ## Cuándo usarla - Después de que una función funciona y pasa tests, pero la implementación es más pesada de lo necesario - Durante revisiones de código cuando se señalan problemas de legibilidad o complejidad - Al encontrar lógica muy anidada, funciones largas o nombres poco claros - Al refactorizar código escrito bajo presión de tiempo o tras fusionar cambios con duplicación ## Cuándo no - El código ya es limpio y legible, o todavía no entiendes qué hace - Es crítico en rendimiento y la versión 'más simple' sería medible más lenta - Estás por reescribir el módulo por completo ## Qué la activa - "Simplifica esta función sin cambiar su comportamiento" - "Revisa este código y sugiere cómo hacerlo más legible" - "Esta lógica anidada es difícil de seguir, ¿cómo la simplifico?" - "Ayúdame a limpiar el código que quedó complicado tras la fusión" ## Archivos - SKILL.md — 13 KB ## SKILL.md Reproducido tal cual desde addyosmani/agent-skills bajo MIT. Esta sección es el documento original y está en inglés. # Code Simplification > Inspired by the [Claude Code Simplifier plugin](https://github.com/anthropics/claude-plugins-official/blob/main/plugins/code-simplifier/agents/code-simplifier.md). 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 Don't 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. ```typescript // 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'; } ``` ```typescript // 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(); 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 (Chesterton's Fence) Before changing or removing anything, understand why it exists. This is Chesterton's Fence: if you see a fence across a road and don't understand why it's there, don't tear it down. First understand the reason, then decide if the reason still applies. ``` 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?) - Check git blame: what was the original context for this code? ``` 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. **Submit refactoring changes separately from feature or bug fix changes.** A PR that refactors and adds a feature is two PRs — split them. ``` 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 ``` Avoid batching multiple simplifications into a single untested change. If something breaks, you need to know which simplification caused it. **The Rule of 500:** If a refactoring would touch more than 500 lines, invest in automation (codemods, sed scripts, AST transforms) rather than making the changes by hand. Manual edits at that scale are error-prone and exhausting to review. ### 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 ```typescript // SIMPLIFY: Unnecessary async wrapper // Before async function getUser(id: string): Promise { return await userService.findById(id); } // After function getUser(id: string): Promise { 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 ```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 ```tsx // SIMPLIFY: Verbose conditional rendering // Before function UserBadge({ user }: Props) { if (user.isAdmin) { return Admin; } else { return User; } } // After function UserBadge({ user }: Props) { const variant = user.isAdmin ? 'admin' : 'default'; const label = user.isAdmin ? 'Admin' : 'User'; return {label}; } // 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 — apply Chesterton's Fence. But accumulated complexity often has no reason; it's just the residue of iteration under pressure. | | "I'll refactor while adding this feature" | Separate refactoring from feature work. Mixed changes are harder to review, revert, and understand in history. | ## 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 ## Dónde encaja - Categoría: [Herramientas para desarrolladores](https://skillsagentes.com/categorias/herramientas-desarrollo.md) — Skills que cambian cómo tu agente escribe, revisa y despliega código. - Creador: [addyosmani](https://skillsagentes.com/creators/addyosmani.md) — 5 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [Security And Hardening](https://skillsagentes.com/skills/addyosmani/agent-skills/security-and-hardening.md): Endurece el código contra vulnerabilidades. Úsalo al manejar entrada de usuario, autenticación, almacenamiento de datos, integraciones externas o datos personales (GDPR, CCPA). - [Spec Driven Development](https://skillsagentes.com/skills/addyosmani/agent-skills/spec-driven-development.md): Crea especificaciones antes de programar: úsalo al iniciar un proyecto o cambio sin spec, cuando los requisitos son ambiguos, o cuando un requerimiento debe descomponerse en un mapa de módulos. - [Code Review And Quality](https://skillsagentes.com/skills/addyosmani/agent-skills/code-review-and-quality.md): Realiza revisión de código en múltiples ejes. Úsalo antes de fusionar cualquier cambio, sea escrito por ti, otro agente o una persona, para evaluar la calidad antes de entrar a la rama principal. - [Planning And Task Breakdown](https://skillsagentes.com/skills/addyosmani/agent-skills/planning-and-task-breakdown.md): Divide el trabajo en tareas ordenadas. Úsalo cuando tengas un spec o requisitos claros y necesites descomponer el trabajo en tareas implementables, estimar alcance o paralelizar. - [Observability And Instrumentation](https://skillsagentes.com/skills/addyosmani/agent-skills/observability-and-instrumentation.md): Instrumenta el código para que el comportamiento en producción sea visible y diagnosticable, con logging, métricas, tracing y alertas. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)