This skill analyzes code for design quality improvements across 8 dimensions: Naming, Object Calisthenics, Coupling & Cohesion, Immutability, Domain Integrity, Type System, Simplicity, and Performance. Ensures rigorous, evidence-based analysis by: (1) Understanding code flow first via implementation-analysis protocol, (2) Systematically evaluating each dimension with specific criteria, (3) Providing actionable findings with file:line references. Triggers when users request: code analysis, design review, refactoring opportunities, code quality assessment, architecture evaluation.
npx skills add https://github.com/NTCoding/claude-skillz --skill lightweight-design-analysis
You are a senior software engineer specializing in type-driven design, domain-driven design, and clean code principles. Your role is to analyze code for design quality improvements with rigorous, evidence-based findings.
Use this skill when analyzing code at class or module level for:
Scope: Small-scale analysis (single class, module, or small set of related files)
Auto-invoke the lightweight-implementation-analysis-protocol skill FIRST.
Before analyzing, you MUST understand:
CRITICAL: Never analyze code you don't fully understand. Evidence-based analysis requires comprehension.
Evaluate the code across 8 dimensions in order. For each dimension, identify specific, evidence-based findings.
Provide structured output with:
For each dimension, apply specific detection criteria. Be rigorous and evidence-based.
Evaluate:
Specific Checks:
❌ AVOID: getUserData(), UtilityClass, helperMethod(), DataProcessor
✅ PREFER: getUserProfile(), OrderCalculator, calculateTotal(), InvoiceGenerator
Look For:
utils/, helpers/, common/, data/doSomething(), handleData(), process()data, result, temp, value (unless truly temporary)Report Format:
🟡 Generic naming at src/utils/DataHelper.ts
- Class name "DataHelper" is too generic
- Consider: OrderValidator, CustomerRepository (based on actual responsibility)
Evaluate against these principles:
Primary Focus: Indentation Levels
Secondary Checks:
Report Format:
🔴 Indentation violation at User.ts:45-67
- Method validateUser() has 3 levels of nesting
- Extract nested logic into separate methods
🟡 ELSE keyword at Order.ts:23
- Can restructure with early return
Evaluate:
Specific Checks:
❌ Feature Envy:
class UserProfile {
displaySubscriptionInfo(): string {
// Accessing multiple properties of Subscription - too much interest in its data
return `Plan: ${this.subscription.planName}, ` +
`Price: $${this.subscription.monthlyPrice}/mo, ` +
`Screens: ${this.subscription.maxScreens}, ` +
`Quality: ${this.subscription.videoQuality}`;
}
}
✅ Refactored (Behavior with Data):
class Subscription {
getDescription(): string {
// Subscription formats its own data
return `Plan: ${this.planName}, ` +
`Price: $${this.monthlyPrice}/mo, ` +
`Screens: ${this.maxScreens}, ` +
`Quality: ${this.videoQuality}`;
}
}
class UserProfile {
displaySubscriptionInfo(): string {
// Delegate to Subscription instead of accessing its internals
return this.subscription.getDescription();
}
}
Look For:
Report Format:
🔴 Feature envy at OrderService.ts:34-42
- Method accesses 5 properties of Customer object
- Consider: Move logic to Customer class or extract to CustomerFormatter
Evaluate:
const when possible?readonly when they shouldn't change?Specific Checks:
❌ AVOID:
let total = 0;
items.forEach(item => total += item.price);
✅ PREFER:
const total = items.reduce((sum, item) => sum + item.price, 0);
Look For:
let instead of constreadonly on class propertiespush(), pop(), splice(), sort()Report Format:
🟡 Mutable state at Cart.ts:12-18
- Array mutated with push() at line 15
- Consider: return new array with [...items, newItem]
Evaluate:
Specific Checks:
❌ Poor encapsulation / Anemic domain:
class PlaceOrderUseCase {
placeOrder(orderId) {
const order = repository.load(orderId)
if (order.getStatus() === 'DRAFT'){
order.place()
}
repository.save(order)
}
}
✅ Domain protects invariants / Tell, Don't Ask :
class PlaceOrderUseCase {
placeOrder(orderId) {
const order = repository.load(orderId)
order.place()
repository.save(order)
}
}
class Order {
...
place() {
if (this.status !== 'DRAFT') {
throw new Error('Cannot place order that is not in draft status')
}
this.status === 'PLACED'
}
}
Look For:
Report Format:
🔴 Anemic domain model at Order.ts:1-15
- Order class only contains data properties
- Business logic found in OrderService.ts:45-89
- Consider: Move calculateTotal(), validateItems() into Order class
Evaluate:
any or as type assertions used?Specific Checks:
❌ AVOID:
status: string; // Can be any string
✅ PREFER:
type OrderStatus = 'pending' | 'confirmed' | 'shipped' | 'delivered';
status: OrderStatus;
Look For:
any keywordas type assertionsstring, number instead of domain types)Report Format:
🔴 Type safety violation at Payment.ts:8
- Property uses 'any' type
- Consider: PaymentMethod type with specific card/paypal/crypto variants
🟡 Primitive obsession at Order.ts:12
- 'status' is string, should be union type
- Consider: type OrderStatus = 'pending' | 'confirmed' | 'shipped'
Evaluate:
Specific Checks:
❌ AVOID:
function calculatePrice(item, discount, tax, shipping, insurance, gift) {
// 8 parameters handling every possible scenario
}
✅ PREFER:
function calculatePrice(item, options) {
// Simple, extensible
}
Look For:
Report Format:
🟡 Code duplication at Cart.ts:23-28 and Cart.ts:45-50
- Same validation logic duplicated
- Extract to: validateItem() method
Evaluate:
Specific Checks:
❌ AVOID:
items.forEach(item => {
const category = categories.find(c => c.id === item.categoryId); // O(n²)
});
✅ PREFER:
const categoryMap = new Map(categories.map(c => [c.id, c])); // O(n)
items.forEach(item => {
const category = categoryMap.get(item.categoryId); // O(1)
});
Look For:
find() or filter() inside loopsIMPORTANT: Only flag performance issues if:
Report Format:
🔴 Performance issue at ProductList.ts:45-52
- Nested find() creates O(n²) complexity
- For 1000 items, this is 1M operations
- Use Map for O(n) solution
Generate a structured report following this template:
# Design Analysis Report
**Analyzed:** [file/module name]
**Lines Reviewed:** [start-end]
## Summary
[2-3 bullet points of key findings]
---
## 🔴 Critical Issues
[Issues that should be addressed before merge/deployment]
### [Dimension] - [Brief Description]
**Location:** file.ts:line
**Issue:** [What's wrong]
**Impact:** [Why it matters]
**Recommendation:** [Specific fix]
\`\`\`typescript
// Current (problematic)
[actual code]
// Suggested
[improved code]
\`\`\`
---
## 🟡 Suggestions
[Improvements that would enhance quality]
[Same format as Critical]
---
## Metrics
- **Dimensions Evaluated:** 8/8
- **Critical Issues:** X
- **Suggestions:** Y
lightweight-implementation-analysis-protocol FIRSTInput: "Analyze the UserService class"
Step 1: Auto-invoke implementation-analysis
Understanding UserService.ts...
- UserService.createUser() [line 23]
↓ validates user data
↓ calls database.insert() [line 45]
↓ sends email via emailService.send() [line 52]
Step 2: Evaluate dimensions
Step 3: Report
# Design Analysis Report
**Analyzed:** UserService.ts
**Lines Reviewed:** 1-120
## Summary
- Feature envy detected: accessing multiple User properties
- Anemic domain model: business logic in service, not domain
---
## 🔴 Critical Issues
### Coupling & Cohesion - Feature Envy
**Location:** UserService.ts:67-72
**Issue:** Method accesses 6 properties of User object directly
**Impact:** High coupling, breaks encapsulation
**Recommendation:** Move logic to User class (Tell, Don't Ask)
\`\`\`typescript
// Current (Feature Envy)
if (user.email && user.verified && user.role === 'admin' && user.createdAt < threshold) {
// complex logic using user internals
}
// Suggested (Tell, Don't Ask)
if (user.isEligibleForAdminPromotion(threshold)) {
// User class encapsulates the logic
}
\`\`\`
---
## 🟡 Suggestions
### Domain Integrity - Anemic Domain Model
**Location:** User.ts:1-25
**Issue:** User class only has getters/setters, no behavior
**Impact:** Business logic scattered in service layer
**Recommendation:** Move validation and business rules into User
\`\`\`typescript
// Current (Anemic)
class User {
public email: string;
public role: string;
}
// In UserService:
if (user.email && isValidEmail(user.email)) { ... }
// Suggested (Rich Domain)
class User {
private email: Email; // Value Object
validateEmail(): void {
// Invariant enforcement
}
}
\`\`\`
---
## Metrics
- **Dimensions Evaluated:** 8/8
- **Critical Issues:** 1
- **Suggestions:** 1
Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation
Use when completing tasks, implementing major features, or before merging to verify work meets requirements
Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping
Comprehensive GitHub code review with AI-powered swarm coordination
Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.
Use this skill to review code. It supports both local changes (staged or working tree) and remote Pull Requests (by ID or URL). It focuses on correctness, maintainability, and adherence to project standards.
Refactor bloated AGENTS.md, CLAUDE.md, or similar agent instruction files to follow progressive disclosure principles. Splits monolithic files into organized, linked documentation.
Create high-quality git commits: review/stage intended changes, split into logical commits, and write clear commit messages (including Conventional Commits). Use when the user asks to commit, craft a commit message, stage changes, or split work into multiple commits.
Take ntcoding/lightweight-design-analysis from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.