ntcoding/claude-skillz/software-design-principles
- community
Checking that the SKILL.md file is still in the repository.
Object-oriented design principles including object calisthenics, dependency inversion, fail-fast error handling, feature envy detection, and intention-revealing naming. Triggers on: writing new classes or functions, refactoring, code review, 'clean up', method longer than 10 lines, feature envy, primitive obsession, deep nesting.
Install
npx vskill@latest install ntcoding/claude-skillz/software-design-principlesSKILL.md
Software Design Principles
Professional software design patterns and principles for writing maintainable, well-structured code.
Critical Rules
🚨 Fail-fast over silent fallbacks. Never use fallback chains (value ?? backup ?? 'unknown'). If data should exist, validate and throw a clear error.
🚨 Strive for maximum type-safety. No `any`. No `as`. Type escape hatches defeat TypeScript's purpose. There's always a type-safe solution.
🚨 Make illegal states unrepresentable. Use discriminated unions, not optional fields. If a state combination shouldn't exist, make the type system forbid it.
🚨 Inject dependencies, don't instantiate. No new SomeService() inside methods. Pass dependencies through constructors.
🚨 Intention-revealing names only. Never use data, utils, helpers, handler, processor. Name things for what they do in the domain.
🚨 No code comments. Comments are a failure to express intent in code. If you need a comment to explain what code does, the code isn't clear enough—refactor it.
🚨 Use Zod for runtime validation. In TypeScript, use Zod schemas for parsing external data, API responses, and user input. Type inference from schemas keeps types and validation in sync.
When This Applies
- Writing new code (these are defaults, not just refactoring goals)
- Refactoring existing code
- Code reviews and design reviews
- During TDD REFACTOR phase
- When analyzing coupling and cohesion
Core Philosophy
Well-designed, maintainable code is far more important than getting things done quickly. Every design decision should favor:
- Clarity over cleverness
- Explicit over implicit
- Fail-fast over silent fallbacks
- Loose coupling over tight integration
- Intention-revealing over generic
Code Without Comments
Never write comments - write expressive code instead.
Object Calisthenics
Apply object calisthenics principles:
The Nine Rules
- One level of indentation per method
- In practice, I will tolerate upto 3
- Don't use the ELSE keyword
- Use early returns instead
- Wrap all primitives and strings
- Create value objects
- Encapsulate validation logic
- Make domain concepts explicit
- First class collections
- Classes with collections should contain nothing else
- One dot per line
- Don't abbreviate
- Use full, descriptive names
- Keep all entities small
- Small classes (< 150 lines)
- Small methods (< 10 lines)
- Small packages/modules
- Easier to understand and maintain
- Avoid getters/setters/properties on entities
- Tell, don't ask
- Objects should do work, not expose data
When to Apply
- During refactoring:
- During code review:
Feature Envy Detection
Method uses another class's data more than its own? Move it there.
Detection: Count external vs own references. More external? Feature envy.
Dependency Inversion Principle
Don't instantiate dependencies inside methods. Inject them.
Scan for: new X() inside methods, static method calls. Extract to constructor.
Fail-Fast Error Handling
NEVER use fallback chains:
Validate and throw clear errors instead:
Error format: Expected [X]. Got [Y]. Context: [debugging info]
Naming Conventions
Principle: Use business domain terminology and intention-revealing names. Never use generic programmer jargon.
Forbidden Generic Names
NEVER use these names:
datautilshelperscommonsharedmanagerhandlerprocessor
These names are meaningless - they tell you nothing about what the code actually does.
Intention-Revealing Names
Instead of generic names, use specific domain language:
Naming Checklist
For classes:
- Does the name reveal what the class is responsible for?
- Is it a noun (or noun phrase) from the domain?
- Would a domain expert recognize this term?
For methods:
- Does the name reveal what the method does?
- Is it a verb (or verb phrase)?
- Does it describe the business operation?
For variables:
- Does the name reveal what the variable contains?
- Is it specific to this context?
- Could someone understand it without reading the code?
Refactoring Generic Names
When you encounter generic names:
- Understand the purpose: What is this really doing?
- Ask domain experts: What would they call this?
- Extract domain concept: Is there a domain term for this?
- Rename comprehensively: Update all references
Type-Driven Design
Principle: Follow Scott Wlaschin's type-driven approach to domain modeling. Express domain concepts using the type system.
Make Illegal States Unrepresentable
Use types to encode business rules:
Avoid Type Escape Hatches
STRICTLY FORBIDDEN without explicit user approval:
anytypeastype assertions (as unknown as,as any,as SomeType)@ts-ignore/@ts-expect-error
There is always a better type-safe solution. These make code unsafe and defeat TypeScript's purpose.
Use the Type System for Validation
Prefer Immutability
Principle: Default to immutable data. Mutation is a source of bugs—unexpected changes, race conditions, and difficult debugging.
The Problem: Mutable State
The Solution: Return New Values
Application Rules
- Prefer
constoverlet - Prefer spread (
...) over mutation - Prefer
map/filter/reduceoverforEachwith mutation - If you must mutate, make it explicit and contained
YAGNI - You Aren't Gonna Need It
Principle: Don't build features until they're actually needed. Speculative code is waste—it costs time to write, time to maintain, and is often wrong when requirements become clear.
The Problem: Speculative Generalization
Application Rules
- Build the simplest thing that works
- Add capabilities when requirements demand them, not before
- "But we might need it" is not a requirement
When Tempted to Cut Corners
STOP if you're about to:
- Use
??chains → fail fast with clear error instead - Use
anyoras→ fix the types, not the symptoms - Use
new X()inside a method → inject through constructor - Name something
data,utils,handler→ use domain language - Add a getter → ask if the object should do the work instead
- Skip refactor because "it works" → refactor IS part of the work
- Write a comment → make the code self-explanatory
- Mutate a parameter → return a new value
- Build "for later" → build what you need now
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingsoftware-design-principles/SKILL.md
Popularity
- Repository stars
- 276
- Repository forks
- 39
- 7-day trend score
- 28
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 23 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/ntcoding/claude-skillz/software-design-principles)