Skip to content
Back to skills

CleanCode

ASecurity

Refactor/clean/simplify code - eliminate duplication, small functions, readable names. USE WHEN user says "clean", "simplify", "refactor", "readable", "messy", "complex", or code has >15 line functions or copy-paste.

  • 666 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added February 8, 2026
developmentjavascripttypescriptgojavarefactoringapi

Works with

  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill cleanCode --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of CleanCode?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for CleanCode
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-cleancode/badge)](https://www.skillsdirectory.com/skills/majiayu000-cleancode)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cleanCode
description: Refactor/clean/simplify code - eliminate duplication, small functions, readable names. USE WHEN user says "clean", "simplify", "refactor", "readable", "messy", "complex", or code has >15 line functions or copy-paste.
---

# Code Simplification

**Core principle:** Code reads like English prose.

**Influences:** Douglas Crockford's "JavaScript: The Good Parts", Robert C. Martin's "Clean Code"

**🚨 TypeScript:** Before writing TypeScript, run `/cleanTypes` for type annotation best practices.

## 1. Small Functions, Clear Names

**Target: 3-15 lines per function.** Name describes exactly what it does.

```typescript
// Bad: Generic name, does multiple things (40 lines)
function process(filename) { ... }

// Good: Small functions with precise names
const extractExtension = (filename) => filename.replace(/.*symlink/, '')
const removeSymlinkAndExtension = (filename) => filename.replace(/\.symlink.*$/, '')
const replaceDOTWithDot = (str) => str.replace(/DOT/g, '.')
```

**Naming rules:**
- Verbs for actions: `createLink()`, `handleExistingFile()`
- Booleans: `isSymlink()`, `hasExtension()`, `canWrite()`
- No generic names: `process()`, `handle()`, `do()` β†’ What specifically?

## 2. No Duplication

If you copy-paste code, stop. Extract a function.

```typescript
// Bad: 3 similar blocks, 40 lines each
function renderIdentity(json) { /* extract fields, print */ }
function renderCard(json) { /* extract fields, print */ }
function renderLogin(json) { /* extract fields, print */ }

// Good: Extract common pattern
function renderEntry(json) {
  const fields = extractFields(json)
  fields.forEach(field => printField(field))
}
```

## 3. Iterate the Source, Not Type Dispatch

**Red flag:** Multiple `extractTypeA()`, `extractTypeB()`, `extractTypeC()` functions.

**Instead:** Iterate the data structure directly.

```javascript
// Bad: Type-specific extractors + dispatch
const extractIdentity = (json) => [/* hardcode identity fields */]
const extractCard = (json) => [/* hardcode card fields */]
const extractLogin = (json) => [/* hardcode login fields */]

if (isIdentity(json)) return extractIdentity(json)
if (isCard(json)) return extractCard(json)
return extractLogin(json)

// Good: Generic extraction - iterate what exists
const extractFields = (json) =>
  Object.entries(json.data || {})
    .filter(([key, value]) => value && typeof value === 'string')
    .map(([key, value]) => ({
      label: humanizeKey(key),
      displayValue: shouldMask(key) ? 'β€’β€’β€’' : value
    }))

// Works for all types, no type checking
```

**Key insight:** Don't ask "what type is this?" Ask "what data exists?"

## 4. Module Splitting: ~250 Lines

When a file exceeds 250 lines, look for natural module boundaries.

```typescript
// Before: links.ts - 247 lines (path utils + file ops + handlers + class + orchestration)

// After: Split by responsibility
// symlink/path-transform.ts - 23 lines
// symlink/file-ops.ts - 40 lines
// symlink/handlers.ts - 43 lines
// symlink/operation.ts - 76 lines
// links.ts - 77 lines (orchestration only)
```

**Don't split prematurely:** 200-line focused file > 5 poorly-abstracted 40-line files.

## 5. Fluent APIs for Sequential Operations

Chain methods to describe operations in natural language.

```typescript
// Bad: Imperative control flow, needs comments
function safeLink(src: string, dest: string | null) {
  // Handle unparseable destination
  if (!dest) return { ... }

  // Handle existing symlink
  if (isSymlink(dest)) { ... }

  // Handle existing file
  if (fileExists(dest)) { ... }

  // Create symlink
  fs.mkdirSync(...)
  return createLink(src, dest)
}

// Good: Reads like English, no comments needed
const safeLink = (src: string, dest: string | null) =>
  new SymlinkOperation(src, dest)
    .handleNullDestination()
    .handleSymlink()
    .handleExistingFile()
    .createSymlink()
    .result()
```

**Implementation pattern:**
```typescript
class Operation {
  private result: Result | null = null

  step1() {
    if (this.result) return this  // Short-circuit if done
    // Check condition, maybe set this.result
    return this
  }

  result() { return this.result! }
}
```

**When to use:** Sequential operations with decision points, each step is a clear named concern.

## 6. Explicit Failures Over Silent Filtering

Make failures visible with error results, don't silently skip.

```typescript
// Bad: Silent failure - lost information
function buildPlan() {
  return files.map(transformPath).filter(path => path !== null)
}
// Which files failed? Unknown.

// Good: Explicit failure - trackable
function buildPlan() {
  return files.map(file => ({ from: file, to: transformPath(file) }))
}

function executePlan(plan: Array<{from: string, to: string | null}>) {
  return plan.map(({ from, to }) => safeLink(from, to))
}

function safeLink(src: string, dest: string | null) {
  if (!dest) return { from: src, to: '<unparseable>', success: false }
  // ... continue
}

// Now: results.filter(r => !r.success).length shows exactly what failed
```

## 7. Eliminate Special Cases

Every special case must justify its existence. Default to uniform handling.

```javascript
// Bad: Unnecessary special case
if (files.length === 1) {
  return handleSingleFile(files[0])
} else {
  return handleMultipleFiles(files)
}

// Good: Unified handling (works for n=1 too)
return files.map(handleFile)
```

**Ask:** "What if I handle both cases uniformly?"

## 8. Arrow Functions for Simple Transformations

```typescript
// Bad: Verbose
function executeSymlinkPlan(plan: SymlinkPlan[]): LinkResult[] {
  const results: LinkResult[] = []
  for (const { from, to } of plan) {
    results.push(safeLink(from, to))
  }
  return results
}

// Good: Concise
const executeSymlinkPlan = (plan: SymlinkPlan[]) =>
  plan.map(({ from, to }) => safeLink(from, to))
```

**Note side effects:** Add comment if `.map()` has side effects (creates files, mutates state).

## Refactoring Checklist

Before code is "done":

1. **Function names read like English?** Should describe exactly what they do
2. **Any copy-pasted code?** Extract to function
3. **Multiple extractType functions?** Replace with `Object.entries(source).map()`
4. **Any function >20 lines?** Break into subfunctions
5. **File >250 lines?** Look for natural module boundaries
6. **Sequential operations with branches?** Consider fluent API
7. **Silently filtering failures?** Make them explicit with error results
8. **Special cases that can be unified?** Handle uniformly when possible

## Complexity Limits

- Function >25 lines β†’ Extract subfunctions
- File >250 lines β†’ Consider splitting by responsibility
- Nested blocks >2 deep β†’ Extract function

**Self-prompt:** "Do I have extractTypeA/B/C functions? Can I iterate the source instead? Would a fluent API make this read better? Are failures explicit? Does the code read like English?"

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.