Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Pragmatic coding standards for writing clean, maintainable code — naming, functions, structure, anti-patterns, and pre-edit safety checks. Use when writing new code, refactoring existing code, reviewing code quality, or establishing coding standards.
Pragmatic coding standards for writing clean, maintainable code — naming, functions, structure, anti-patterns, and pre-edit safety checks. Use when writing new code, refactoring existing code, reviewing code quality, or establishing coding standards.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
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.
npx clawhub@latest install clean-code
PrincipleRulePractical TestSRPSingle 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?"
Names are the most important documentation. A good name eliminates the need for a comment. ElementConventionBadGoodVariablesReveal intentn, d, tmpuserCount, elapsed, activeUsersFunctionsVerb + nounuser(), calc()getUserById(), calculateTotal()BooleansQuestion formactive, flagisActive, hasPermission, canEditConstantsSCREAMING_SNAKEmax, timeoutMAX_RETRY_COUNT, REQUEST_TIMEOUT_MSClassesNoun, singularManager, DataUserRepository, OrderServiceEnumsPascalCase values'pending' stringStatus.Pending Rule: If you need a comment to explain a name, rename it.
Anti-PatternProblemFixCryptic abbreviations (usrMgr, cfg)Unreadable in 6 monthsSpell it out — IDE autocomplete makes long names freeGeneric names (data, info, item, handler)Says nothing about purposeUse domain-specific names that reveal intentMisleading names (getUserList returns one user)Actively deceives readersMatch name to behavior, or change the behaviorHungarian notation (strName, nCount, IUser)Redundant with type systemLet TypeScript/IDE show types; names describe purpose
RuleGuidelineWhySmallMax 20 lines, ideally 5-10Fits in your headOne ThingDoes one thing, does it wellTestable and nameableOne LevelOne level of abstraction per functionReadable top to bottomFew ArgsMax 3 arguments, prefer 0-2Easy to call correctlyNo Side EffectsDon't mutate inputs unexpectedlyPredictable behavior
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); }
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', });
PatternWhen to ApplyBenefitGuard ClausesEdge cases at function startFlat, readable flowFlat > NestedAny nesting beyond 2 levelsReduced cognitive loadCompositionComplex operationsSmall, testable piecesColocationRelated code across filesEasier to find and changeExtract FunctionComments separating "sections"Self-documenting code
// 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 }; }
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-PatternProblemFixComment every lineNoise obscures signalDelete obvious comments; comment why, not whatHelper for one-linerUnnecessary indirectionInline the codeFactory for 2 objectsOver-engineeringDirect instantiationutils.ts with 1 functionJunk drawer filePut code where it's usedDeep nestingUnreadable flowGuard clauses and early returnsMagic numbersUnclear intentNamed constantsGod functionsUntestable, unreadableSplit by responsibilityCommented-out codeDead code confusionDelete it; git remembersTODO sprawlNever gets doneTrack in issue tracker, not codePremature abstractionWrong abstraction is worse than noneWait for 3+ duplicates before abstractingCopy-paste programmingDuplicated bugsExtract shared logicException-driven control flowSlow and confusingUse explicit conditionalsStringly-typed codeTypos and missed casesUse enums or union typesCallback hellPyramid of doomUse async/await
Before changing any file, answer these questions to avoid cascading breakage: QuestionWhyWhat imports this file?Dependents might break on interface changesWhat does this file import?You might need to update the contractWhat tests cover this?Tests might fail — update them alongside codeIs 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.
Before marking any task complete, verify: CheckQuestionGoal 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 add comments that restate the code — if the code needs a comment to explain what it does, rename things until it doesn't NEVER create abstractions for fewer than 3 use cases — premature abstraction is worse than duplication NEVER leave commented-out code in the codebase — delete it; version control exists for history NEVER write functions longer than 20 lines — extract sub-functions until each does one thing NEVER nest deeper than 2 levels — use guard clauses, early returns, or extract functions NEVER use magic numbers or strings — define named constants with clear semantics 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 NEVER leave a task with failing lint or type checks — fix all errors before marking complete
Detailed guides for specific clean code topics: ReferenceDescriptionAnti-Patterns21 common mistakes with bad/good code examples across naming, functions, structure, and commentsCode SmellsClassic code smells catalog with detection patterns — Bloaters, OO Abusers, Change Preventers, Dispensables, CouplersRefactoring CatalogEssential refactoring patterns with before/after examples and step-by-step mechanics
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.