clean-code
Clean Code provides a disciplined framework for writing readable, maintainable code through meaningful naming conventions, small focused functions, and consistent error handling practices. Apply this skill when reviewing code quality, refactoring long functions, establishing naming standards, improving unit test design, or evaluating pull requests for clarity and adherence to the Single Responsibility Principle.
git clone --depth 1 https://github.com/wondelai/skills /tmp/clean-code && cp -r /tmp/clean-code/clean-code ~/.claude/skills/clean-codeSKILL.md
# Clean Code Framework A disciplined approach to writing code that communicates intent, minimizes surprises, and welcomes change. Apply these principles when writing new code, reviewing pull requests, refactoring legacy systems, or advising on code quality. ## Core Principle **Code is read far more often than it is written — optimize for the reader.** The read-to-write ratio is well over 10:1, so every naming choice, function boundary, and formatting decision either adds clarity or adds cost. Clean code reads like well-written prose: names reveal intent, functions tell a story one step at a time, and the Boy Scout Rule applies — always leave the code cleaner than you found it. ## Scoring **Goal: 10/10.** Rate any code 0-10 against the principles below. Report the current score and the specific improvements needed to reach 10/10. - **9-10:** Names reveal intent, functions are small and focused, error handling is consistent, tests are clean and comprehensive - **7-8:** Mostly clean with minor naming ambiguities or a few long functions; tests may lack edge cases - **5-6:** Mixed — good patterns alongside unclear names, duplicated logic, or inconsistent error handling - **3-4:** Long multi-purpose functions, misleading names, poor or missing tests - **1-2:** Nearly unreadable — magic numbers, cryptic abbreviations, no structure, no tests ## The Clean Code Framework Six disciplines for writing code that communicates clearly and adapts to change: ### 1. Meaningful Names **Core concept:** Names should reveal intent, avoid disinformation, and make the code read like prose. If a name requires a comment to explain it, the name is wrong. **Why it works:** Names are the most pervasive form of documentation — a well-chosen name eliminates the need to read the implementation; a poor one forces every reader to reverse-engineer intent. **Key insights:** - A name should answer why it exists, what it does, and how it is used - No encodings, prefixes, or type information (no Hungarian notation); single letters only for tiny-scope loop counters - Classes are nouns; methods are verbs - One word per concept: don't mix `fetch`, `retrieve`, and `get` - Longer scope demands a longer, more descriptive name - Rename freely — IDEs make it trivial **Code applications:** | Context | Pattern | Example | |---------|---------|---------| | **Variables** | Intention-revealing | `elapsedTimeInDays` not `d` | | **Booleans** | Predicate phrasing | `isActive`, `hasPermission`, `canEdit` | | **Functions** | Verb + noun | `calculateMonthlyRevenue()` not `calc()` | | **Classes** | Noun naming the responsibility | `InvoiceGenerator` not `InvoiceManager` | See: [references/naming-conventions.md](references/naming-conventions.md) ### 2. Functions **Core concept:** Functions should be small, do one thing, and do it well — ideally 4-6 lines, zero to two arguments, one level of abstraction. **Why it works:** Small single-purpose functions are easy to name, understand, test, and reuse; long functions hide bugs, resist testing, and accumulate responsibilities. **Key insights:** - Step-Down Rule: code reads top-down, each function calling the next level of abstraction - Argument count: zero best, one fine, two acceptable, three+ requires justification - Flag arguments are a smell — the function does two things; split it - Command-Query Separation: change state or return a value, never both - Extract till you drop: if you can pull out a named function, do it - No hidden side effects — the name must tell the whole truth **Code applications:** | Context | Pattern | Example | |---------|---------|---------| | **Long function** | Extract named steps | `validateInput(); transformData(); saveRecord();` | | **Flag argument** | Split into two functions | `renderForPrint()` / `renderForScreen()` not `render(isPrint)` | | **Error cases** | Guard clauses at top | Early return for errors, single happy path | | **Many arguments** | Introduce parameter object | `new DateRange(start, end)` not `report(start, end, format, locale)` | | **Side effects** | Make effects explicit | `checkPassword()` that starts a session → rename or separate | See: [references/functions-and-methods.md](references/functions-and-methods.md) ### 3. Comments and Formatting **Core concept:** A comment is a failure to express yourself in code. When comments are necessary, they explain *why*, never *what*. Formatting creates the visual structure that makes code scannable. **Why it works:** Comments rot — code changes but comments often don't, creating documentation worse than none. Clean formatting lets developers scan code like a newspaper: headlines first, details on demand. **Key insights:** - The best comment is a well-named extracted function - Acceptable: legal headers, TODOs, public API docs, genuine "why" explanations - Commented-out code and journal comments: delete — version control remembers - Vertical openness between concepts; vertical density within them; declare variables near usage - Newspaper metaphor: high-level functions at the top of the file, details below **Code applications:** | Context | Pattern | Example | |---------|---------|---------| | **Explaining "what"** | Replace with better name | `// check if eligible` → `isEligible()` | | **Explaining "why"** | Keep as comment | `// RFC 7231 requires this header for proxies` | | **Commented-out code** | Delete it | Trust version control | | **Team formatting** | Decide once, automate | Prettier, Black, gofmt | See: [references/comments-formatting.md](references/comments-formatting.md) ### 4. Error Handling **Core concept:** Error handling is a separate concern from business logic. Use exceptions rather than return codes, provide context with every exception, and never return or pass null. **Why it works:** Return codes clutter the happy path with checks; exceptions separate the two cleanly. Returning null forces null checks on every caller, and one missing check crashes far from th
Build lean, opinionated products using the 37signals philosophy from "Getting Real", "Rework", and "Shape Up". Use when the user mentions "Getting Real", "Rework", "Shape Up", "37signals", "Basecamp method", "six-week cycles", "fixed time variable scope", "appetite vs estimates", "betting table", "breadboarding", "fat marker sketch", "build less", "underdo the competition", "opinionated software", "we have too many meetings", "the project keeps growing", "how do we ship faster", or "stop overbuilding". Also trigger when cutting scope to ship sooner, fighting feature creep, running a small team, avoiding long-term roadmaps, or killing unnecessary meetings. Covers shaping, betting, building, and the art of saying no. For MVP validation, see lean-startup. For design sprints, see design-sprint.
Create uncontested market space using value innovation instead of competing head-to-head. Use when the user mentions "blue ocean", "red ocean", "strategy canvas", "ERRC framework", "value innovation", "non-customers", "buyer utility map", "uncontested market", "stop competing on price", "everyone is undercutting us", "the market is too crowded", or "how do we stand out". Also trigger when comparing pricing strategies, exploring new market categories, finding underserved or non-customers, or escaping a brutal price war. Covers the Four Actions Framework, buyer utility map, and value-cost trade-offs. For tech adoption strategy, see crossing-the-chasm. For product positioning, see obviously-awesome.
Structure software around the Dependency Rule: source code dependencies point inward from frameworks to use cases to entities. Use when the user mentions "architecture layers", "dependency rule", "ports and adapters", "hexagonal architecture", "onion architecture", "screaming architecture", "where should business logic go", "decouple from the database", "swap the framework without a rewrite", "business logic is tangled with the framework", or "keep business rules independent". Also trigger when deciding which layer code belongs in, isolating core logic from infrastructure, defining module boundaries, or debating whether the framework should call your code or the reverse. Covers component principles, boundaries, and SOLID. For code-level quality, see clean-code. For domain modeling, see domain-driven-design.
Engineer word-of-mouth and virality using the STEPPS framework (Social Currency, Triggers, Emotion, Public, Practical Value, Stories). Use when the user mentions "go viral", "word of mouth", "shareable content", "social currency", "why people share", "viral loop", "referral program", "organic growth", "how do I get people to share this", "nobody is sharing it", or "make this spread". Also trigger when designing shareable features, crafting social campaigns, or building products that spread through peer recommendation. Covers environmental triggers and high-arousal emotional content. For sticky messaging, see made-to-stick. For persuasion tactics, see influence-psychology.
Build a weekly cadence of customer touchpoints using Opportunity Solution Trees, assumption mapping, and interview snapshots. Use when the user mentions "continuous discovery", "opportunity solution tree", "weekly interviews", "assumption testing", "discovery habits", "product trio", "outcome-based roadmap", "how do I talk to customers regularly", "we keep building things nobody uses", or "connect research to the roadmap". Also trigger when setting up regular customer feedback loops, prioritizing which experiments to run, or tying discovery insights to delivery work. Covers experience mapping, co-creation, and prioritizing opportunities. For interview technique, see mom-test. For team structure, see inspired-product.
Audit websites and landing pages for conversion issues and design evidence-based A/B tests. Use when the user mentions "landing page isnt converting", "conversion rate", "A/B test", "why visitors leave", "objection handling", "bounce rate", "split testing", "conversion funnel", "increase signups", "people add to cart but dont buy", or "improve conversions". Also trigger when diagnosing why signups are low, designing experiment hypotheses, or auditing checkout flows for friction points. Covers funnel mapping, persuasion assets, and objection/counter-objection frameworks. For overall marketing strategy, see one-page-marketing. For usability issues, see ux-heuristics.
Navigate the technology adoption lifecycle from early adopters to mainstream market. Use when the user mentions "crossing the chasm", "beachhead segment", "whole product", "early adopters vs mainstream", "tech go-to-market", "bowling pin strategy", "technology adoption lifecycle", "pragmatist buyers", "growth stalled after early adopters", "cant get mainstream customers", or "our go-to-market plan". Also trigger when a startup has early traction but cant grow beyond initial users, or when planning go-to-market for a technical product. Covers the D-Day analogy, bowling-pin strategy, and positioning against incumbents. For product positioning, see obviously-awesome. For new market creation, see blue-ocean-strategy.
Design data systems by understanding storage engines, replication, partitioning, transactions, and consistency models. Use when the user mentions "database choice", "which database should I use", "SQL or NoSQL", "replication lag", "partitioning strategy", "consistency vs availability", "stream processing", "ACID transactions", "eventual consistency", "my queries are slow at scale", or "data is inconsistent across replicas". Also trigger when choosing a datastore, designing data pipelines, or debugging distributed-system consistency issues. Covers data models, batch/stream processing, and distributed consensus. For system design, see system-design. For resilience, see release-it.