Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
bighardperson avatar

Clean Code

  • 8 installs
  • 33 repo stars
  • Updated April 26, 2026
  • bighardperson/computer-science-skills-collection

Clean-code is a skill that provides pragmatic coding standards for writing clean, maintainable code covering naming, functions, structure, and anti-patterns.

About

Clean-code is a skill that provides pragmatic coding standards for writing and reviewing maintainable code. It covers naming rules, function rules, code structure patterns, and common anti-patterns, with principles like SRP, DRY, KISS, and YAGNI. A developer uses it when writing new code, refactoring, or reviewing code quality.

  • Pragmatic coding standards for clean, maintainable code
  • Covers naming, functions, structure, and anti-patterns
  • SRP, DRY, KISS, YAGNI, and guard-clause guidance with examples

Clean Code by the numbers

  • 8 all-time installs (skills.sh)
  • Ranked #837 of 1,354 Code Review & Quality skills by installs in the Skillselion catalog
  • Data as of Jul 30, 2026 (Skillselion catalog sync)
At a glance

clean-code capabilities & compatibility

Capabilities
code review · refactoring
Use cases
code review · refactoring
Pricing
Free
From the docs

What clean-code says it does

Pragmatic coding standards for writing clean, maintainable code — naming, functions, structure, anti-patterns, and pre-edit safety checks.
SKILL.md
Clean code reads like well-written prose — every name reveals intent, every function does one thing, and every abstraction earns its place.
SKILL.md
Flatten nested conditionals with early returns. Never nest deeper than 2 levels.
SKILL.md
npx skills add https://github.com/bighardperson/computer-science-skills-collection --skill clean-code

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs8
repo stars33
Last updatedApril 26, 2026
Repositorybighardperson/computer-science-skills-collection

What it does

Apply naming, function, and structure standards when writing, refactoring, or reviewing code for quality.

Who is it for?

Writing new code, refactoring, or reviewing code quality against clean-code standards.

Skip if: Language-specific framework setup or security scanning.

When should I use this skill?

Writing new code, refactoring existing code, or establishing coding standards.

What you get

Applies naming, function, and structure rules for maintainable code.

  • Naming and function-rule guidance
  • Refactoring patterns with examples

By the numbers

  • 5 core principles: SRP, DRY, KISS, YAGNI, Boy Scout
  • Functions capped at max 20 lines and 3 arguments

Files

SKILL.mdMarkdownGitHub ↗

Clean Code

Be concise, direct, and solution-focused. Clean code reads like well-written prose — every name reveals intent, every function does one thing, and every abstraction earns its place.

Installation

OpenClaw / Moltbot / Clawbot

npx clawhub@latest install clean-code

---

Core Principles

PrincipleRulePractical Test
SRPSingle Responsibility — each function/class does ONE thing"Can I describe what this does without using 'and'?"
DRYDon't Repeat Yourself — extract duplicates, reuse"Have I written this logic before?"
KISSKeep It Simple — simplest solution that works"Is there a simpler way to achieve this?"
YAGNIYou Aren't Gonna Need It — don't build unused features"Does anyone need this right now?"
Boy ScoutLeave code cleaner than you found it"Is this file better after my change?"

---

Naming Rules

Names are the most important documentation. A good name eliminates the need for a comment.

ElementConventionBadGood
VariablesReveal intentn, d, tmpuserCount, elapsed, activeUsers
FunctionsVerb + nounuser(), calc()getUserById(), calculateTotal()
BooleansQuestion formactive, flagisActive, hasPermission, canEdit
ConstantsSCREAMING_SNAKEmax, timeoutMAX_RETRY_COUNT, REQUEST_TIMEOUT_MS
ClassesNoun, singularManager, DataUserRepository, OrderService
EnumsPascalCase values'pending' stringStatus.Pending
Rule: If you need a comment to explain a name, rename it.

Naming Anti-Patterns

Anti-PatternProblemFix
Cryptic abbreviations (usrMgr, cfg)Unreadable in 6 monthsSpell it out — IDE autocomplete makes long names free
Generic names (data, info, item, handler)Says nothing about purposeUse domain-specific names that reveal intent
Misleading names (getUserList returns one user)Actively deceives readersMatch name to behavior, or change the behavior
Hungarian notation (strName, nCount, IUser)Redundant with type systemLet TypeScript/IDE show types; names describe purpose

---

Function Rules

RuleGuidelineWhy
SmallMax 20 lines, ideally 5-10Fits in your head
One ThingDoes one thing, does it wellTestable and nameable
One LevelOne level of abstraction per functionReadable top to bottom
Few ArgsMax 3 arguments, prefer 0-2Easy to call correctly
No Side EffectsDon't mutate inputs unexpectedlyPredictable behavior

Guard Clauses

Flatten nested conditionals with early returns. Never nest deeper than 2 levels.

// BAD — 5 levels deep
function processOrder(order: Order) {
  if (order) {
    if (order.items.length > 0) {
      if (order.customer) {
        if (order.customer.isVerified) {
          return submitOrder(order);
        }
      }
    }
  }
  throw new Error('Invalid order');
}

// GOOD — guard clauses flatten the structure
function processOrder(order: Order) {
  if (!order) throw new Error('No order');
  if (!order.items.length) throw new Error('No items');
  if (!order.customer) throw new Error('No customer');
  if (!order.customer.isVerified) throw new Error('Customer not verified');

  return submitOrder(order);
}

Parameter Objects

When a function needs more than 3 arguments, use an options object.

// BAD — too many parameters, order matters
createUser('John', 'Doe', 'john@example.com', 'secret', 'admin', 'Engineering');

// GOOD — self-documenting options object
createUser({
  firstName: 'John',
  lastName: 'Doe',
  email: 'john@example.com',
  password: 'secret',
  role: 'admin',
  department: 'Engineering',
});

---

Code Structure Patterns

PatternWhen to ApplyBenefit
Guard ClausesEdge cases at function startFlat, readable flow
Flat > NestedAny nesting beyond 2 levelsReduced cognitive load
CompositionComplex operationsSmall, testable pieces
ColocationRelated code across filesEasier to find and change
Extract FunctionComments separating "sections"Self-documenting code

Composition Over God Functions

// BAD — god function doing everything
async function processOrder(order: Order) {
  // Validate... (15 lines)
  // Calculate totals... (15 lines)
  // Process payment... (10 lines)
  // Send notifications... (10 lines)
  // Update inventory... (10 lines)
  return { success: true };
}

// GOOD — composed of small, focused functions
async function processOrder(order: Order) {
  validateOrder(order);
  const totals = calculateOrderTotals(order);
  const payment = await processPayment(order.customer, totals);
  await sendOrderConfirmation(order, payment);
  await updateInventory(order.items);
  return { success: true, orderId: payment.orderId };
}

---

Return Type Consistency

Functions should return consistent types. Use discriminated unions for multiple outcomes.

// BAD — returns different types
function getUser(id: string) {
  const user = database.find(id);
  if (!user) return false;     // boolean
  if (user.isDeleted) return null; // null
  return user;                 // User
}

// GOOD — discriminated union
type GetUserResult =
  | { status: 'found'; user: User }
  | { status: 'not_found' }
  | { status: 'deleted' };

function getUser(id: string): GetUserResult {
  const user = database.find(id);
  if (!user) return { status: 'not_found' };
  if (user.isDeleted) return { status: 'deleted' };
  return { status: 'found', user };
}

---

Anti-Patterns

Anti-PatternProblemFix
Comment every lineNoise obscures signalDelete obvious comments; comment why, not what
Helper for one-linerUnnecessary indirectionInline the code
Factory for 2 objectsOver-engineeringDirect instantiation
utils.ts with 1 functionJunk drawer filePut code where it's used
Deep nestingUnreadable flowGuard clauses and early returns
Magic numbersUnclear intentNamed constants
God functionsUntestable, unreadableSplit by responsibility
Commented-out codeDead code confusionDelete it; git remembers
TODO sprawlNever gets doneTrack in issue tracker, not code
Premature abstractionWrong abstraction is worse than noneWait for 3+ duplicates before abstracting
Copy-paste programmingDuplicated bugsExtract shared logic
Exception-driven control flowSlow and confusingUse explicit conditionals
Stringly-typed codeTypos and missed casesUse enums or union types
Callback hellPyramid of doomUse async/await

---

Pre-Edit Safety Check

Before changing any file, answer these questions to avoid cascading breakage:

QuestionWhy
What imports this file?Dependents might break on interface changes
What does this file import?You might need to update the contract
What tests cover this?Tests might fail — update them alongside code
Is this a shared component?Multiple consumers means wider blast radius
File to edit: UserService.ts
├── Who imports this? → UserController.ts, AuthController.ts
├── Do they need changes too? → Check function signatures
└── What tests cover this? → UserService.test.ts
Rule: Edit the file + all dependent files in the SAME task. Never leave broken imports or missing updates.

---

Self-Check Before Completing

Before marking any task complete, verify:

CheckQuestion
Goal met?Did I do exactly what was asked?
Files edited?Did I modify all necessary files, including dependents?
Code works?Did I verify the change compiles and runs?
No errors?Do lint and type checks pass?
Nothing forgotten?Any edge cases or dependent files missed?

---

NEVER Do

1. NEVER add comments that restate the code — if the code needs a comment to explain what it does, rename things until it doesn't 2. NEVER create abstractions for fewer than 3 use cases — premature abstraction is worse than duplication 3. NEVER leave commented-out code in the codebase — delete it; version control exists for history 4. NEVER write functions longer than 20 lines — extract sub-functions until each does one thing 5. NEVER nest deeper than 2 levels — use guard clauses, early returns, or extract functions 6. NEVER use magic numbers or strings — define named constants with clear semantics 7. NEVER edit a file without checking what depends on it — broken imports and missing updates are the most common source of bugs in multi-file changes 8. NEVER leave a task with failing lint or type checks — fix all errors before marking complete

---

References

Detailed guides for specific clean code topics:

ReferenceDescription
Anti-Patterns21 common mistakes with bad/good code examples across naming, functions, structure, and comments
Code SmellsClassic code smells catalog with detection patterns — Bloaters, OO Abusers, Change Preventers, Dispensables, Couplers
Refactoring CatalogEssential refactoring patterns with before/after examples and step-by-step mechanics

Related skills

FAQ

What principles does it cover?

SRP, DRY, KISS, YAGNI, and the Boy Scout rule.

How long should a function be?

Max 20 lines, ideally 5-10, doing one thing.

Code Review & Qualitybackendfrontend

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.