Skip to main content

clean-code

Clean, maintainable, human-readable code principles combined with anti-over-engineering discipline: naming, single responsibility, DRY, and scoping changes to exactly what was requested. Use when writing new code, refactoring existing code, reviewing code for quality, or deciding how much abstraction a change actually needs.

Source facts

Repository
Mindrally/skills
Last source activity
September 3, 2026 at 15:58
Detected SKILL.md language
English
Stars
264
Forks
41

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
clean-code
description
Clean, maintainable, human-readable code principles combined with anti-over-engineering discipline: naming, single responsibility, DRY, and scoping changes to exactly what was requested. Use when writing new code, refactoring existing code, reviewing code for quality, or deciding how much abstraction a change actually needs.
# Clean Code This skill covers writing code that is easy to read and change, and — just as important — avoiding the over-engineering that makes code harder to read and change in the name of "best practices." Both halves matter together: clean code is simple code, not merely well-decorated code. ## Workflow for Writing or Reviewing Code 1. **Scope the change** — Identify exactly what was asked for. Note what's out of scope before writing anything. 2. **Reach for the simplest solution first** — Prefer the direct, obvious implementation over a general or configurable one, unless a concrete current need justifies more. 3. **Name things for their purpose** — Choose names that reveal intent before writing the body of a function or the shape of a type. 4. **Keep functions single-purpose** — If a function needs a comment to explain what it does, split it. 5. **Remove duplication deliberately** — Extract shared logic only once it's actually duplicated (see Rule of Three below), not preemptively. 6. **Write or update tests** — Cover the new behavior and the edge cases it introduces. 7. **Verify scope before delivery** — Confirm only the requested code changed, check for a simpler approach you might have missed, and confirm no unrequested files were touched. ## Meaningful Names - Variables, functions, and classes should reveal their purpose from the name alone. - Names should explain why something exists and how it's used, not just its type or contents (`activeUserIds`, not `list1`). - Avoid abbreviations unless they're universally understood in the domain (`id`, `url` — fine; `usrCfgTmp` — not fine). ## Constants Over Magic Numbers - Replace hard-coded values with named constants (`MAX_RETRY_COUNT = 3`, not a bare `3` three call sites later). - Use descriptive constant names that explain the value's purpose, not just its value. - Keep constants at the top of the file or in a dedicated constants module when shared across files. ## Smart Comments - Don't comment on what the code does — make the code self-documenting through naming and structure instead. - Use comments to explain *why* something is done a certain way, especially when the reason isn't visible in the code (a workaround for a library bug, a non-obvious ordering requirement). - Document public APIs, genuinely complex algorithms, and non-obvious side effects. ## Single Responsibility - Each function should do exactly one thing. - Functions should be small and focused enough to be understood without scrolling. - If a function needs a comment to explain what it does, that's a signal to split it into named sub-functions instead. ## DRY — Don't Repeat Yourself - Extract repeated code into reusable functions once the repetition is real, not anticipated. - Share common logic through a proper abstraction — a shared function or module, not copy-paste with tweaks. - Maintain a single source of truth for any given piece of business logic or configuration value. ## Encapsulation - Hide implementation details behind a clear interface; callers shouldn't need to know how a thing works to use it. - Move nested conditionals into well-named functions or guard clauses instead of deep `if`/`else` trees. ```js // Before function canCheckout(cart) { if (cart.items.length > 0) { if (cart.user.isVerified) { if (cart.total <= cart.user.creditLimit) { return true; } } } return false; } // After function canCheckout(cart) { const hasItems = cart.items.length > 0; const isWithinCreditLimit = cart.total <= cart.user.creditLimit; return hasItems && cart.user.isVerified && isWithinCreditLimit; } ``` ## Clean Structure - Keep related code together (a feature's components, hooks, and styles in one directory, not scattered by file type). - Organize code in a logical hierarchy that mirrors how the domain is understood. - Use consistent file and folder naming conventions across the codebase. ## Avoiding Over-Engineering - Only change what was asked. The simplest solution that satisfies the request comes first. - When the right level of abstraction is unclear, ask rather than guessing toward the more elaborate option. - Do not modify unrequested code, even if it looks improvable — a drive-by refactor in an unrelated function expands the review surface and the risk of the change. - Do not add abstractions (interfaces, factories, plugin systems, config layers) without a concrete, current need. A single implementation doesn't need an interface "in case" a second one shows up later — that's speculative generality (YAGNI: "You Aren't Gonna Need It"). - Do not import a new dependency to solve a problem a few lines of existing code already solve. - Do not rewrite entire files for small changes — a targeted diff is easier to review and safer to ship than a full-file rewrite. - Do not add error handling for scenarios that cannot occur given the surrounding code's guarantees — defensive code for impossible states adds reading cost without adding safety. ### Rule of Three - Tolerate duplication the first two times a pattern appears. - Extract an abstraction on the third occurrence, once the actual shape of the shared logic is clear — extracting after one or two instances often guesses wrong about what's actually shared. ### Signs of Over-Engineering - A configuration option that has only ever been set to one value. - An interface with exactly one implementation and no test double that needs a second. - A generic `options` object accreting fields for hypothetical future callers. - A plugin/strategy pattern introduced before there are two strategies to switch between. ## Code Quality Maintenance - Refactor continuously in small steps rather than deferring cleanup to a dedicated "refactor sprint." - Fix technical debt early, while the context for why the code looks the way it does is still fresh. - Leave code cleaner than you found it, scoped to the area you're already touching — not as license to refactor unrelated files. ## Testing - Write a failing test before fixing a bug, so the fix is verified and the bug can't silently regress. - Keep tests readable and maintainable — a test that's harder to understand than the code it tests has failed at its job. - Test edge cases and error conditions explicitly, not just the happy path. ## Version Control - Write clear, specific commit messages that explain why a change was made. - Make small, focused commits — one logical change per commit. - Use meaningful branch names that describe the work, not the author or the date. ## Before Delivery Checklist - Only the requested code changed — no unrelated files touched. - No abstraction was added without a concrete need that exists today. - No dependency was added that duplicates something already available. - A simpler approach was considered and ruled out, not just skipped. - New behavior has test coverage, including at least one edge case.
View on GitHub