This skill should be used when evaluating complexity, planning features, or when over-engineering, simpler, is this overkill, or keep it simple are mentioned.
This skill should be used when evaluating complexity, planning features, or when over-engineering, simpler, is this overkill, or keep it simple are mentioned.
metadata
{"version":"1.0.2"}
Challenge Complexity
Systematic pushback against over-engineering → justified simplicity.
<when_to_use>
Planning features or architecture
Choosing frameworks, libraries, patterns
Evaluating proposed solutions
Detecting premature optimization or abstraction
Build vs buy decisions
NOT for: trivial tasks, clear requirements with validated complexity, regulatory/compliance-mandated approaches
</when_to_use>
Load the maintain-tasks skill when applying framework to non-trivial proposals:
Stage
Trigger
activeForm
Identify
Complexity smell detected
"Identifying complexity smell"
Alternative
Generating simpler options
"Proposing simpler alternatives"
Question
Probing constraints
"Questioning constraints"
Document
Recording decision
"Documenting decision"
Task format:
- Identify { complexity type } smell
- Propose alternatives to { specific approach }
- Question { constraint/requirement }
- Document { decision/rationale }
Workflow:
Start: Create Identify in_progress when smell detected
Transition: Mark current completed, add next in_progress
Skip to Document if complexity validated immediately
Optional stages: skip Alternative if obvious, skip Question if constraints clear
Adjust tone based on severity:
◇ Alternative (Minor complexity):
"Interesting approach. Help me understand why X over the more common Y?"
◆ Caution (Moderate risk):
"This pattern often leads to { specific problems }. Are we solving for something I'm not seeing?"
◈ Hazard (High risk):
"This violates { principle } and will likely cause { specific issues }. I strongly recommend { alternative }. If we must proceed, we need to document the reasoning."
Common complexity smells to watch for:
Build vs Buy: Custom solution when proven libraries exist
Custom auth system → Auth0, Clerk, BetterAuth
Custom validation → Zod, Valibot, ArkType
Custom state management → Zustand, Jotai, Nanostores
Custom form handling → React Hook Form, Formik
Indirect Solutions: Solving problem A by first solving problems B, C, D
Compiling TS→JS then using JS → Use TS directly in build tool
Reading file, transforming, writing back → Use stream processing
Storing in DB to pass between functions → Pass data directly
Premature Abstraction: Layers "for flexibility" without concrete future requirements
Plugin systems for 1 use case
Factories for single implementations
Dependency injection for stateless functions
Generic repositories for 1 data source
Performance Theater: Optimizing without measurements or clear bottlenecks
Caching before measuring load
Debouncing without user complaints
Worker threads for CPU-light tasks
Memoization of cheap calculations
Security Shortcuts: Disabling security features instead of configuring properly
CORS: * → Configure specific origins
any types for external data → Runtime validation with Zod
Storing secrets in code → Environment variables + vault
Framework Overkill: Heavy frameworks for simple tasks
React for static content → HTML + CSS
Redux for local UI state → useState
GraphQL for simple CRUD → REST
Microservices for small apps → Monolith first
Custom Infrastructure: Building platform features that cloud providers offer
Custom logging → CloudWatch, Datadog
Custom metrics → Prometheus, Grafana
Custom secrets → AWS Secrets Manager, Vault
Custom CI/CD → GitHub Actions, CircleCI
<red_flags>
Watch for these justifications — reframe with specific questions:
"We might need it later"
→ "What specific requirement do we have now?"
"It's more flexible"
→ "What flexibility do we need that the simple approach doesn't provide?"
"It's best practice"
→ "Best practice for what context? Does that context match ours?"
"It's faster"
→ "Have you measured? What's the performance requirement?"
"Everyone does it this way"
→ "For problems of this scale? Do they have our constraints?"
"It's more enterprise-ready"
→ "What enterprise requirement are we meeting?"
"I read about it on Hacker News"
→ "Does their problem match ours?"
</red_flags>
Guide toward simpler alternatives with concrete examples:
Feature Flags over Plugin Architecture
// ComplexinterfacePlugin {
transform(data: Data): Data;
}
const plugins = loadPlugins();
let result = data;
for (const plugin of plugins) {
result = plugin.transform(result);
}
// Simpleconst features = getFeatureFlags();
let result = data;
if (features.transformA) {
result = transformA(result);
}
if (features.transformB) {
result = transformB(result);
}
Direct over Generic
// Complex (premature abstraction)interfaceDataStore<T> {
get(id: string): Promise<T>;
}
classPostgresStore<T> implementsDataStore<T> {
/* ... */
}
const users = newPostgresStore<User>({
/* config */
});
// Simple (direct, refactor later if needed)asyncfunctiongetUser(id: string): Promise<User> {
returnawait db.query("SELECT * FROM users WHERE id = $1", [id]);
}