| name | lightweight-software-principles |
| description | Use when implementing small or low-complexity changes with minimal ceremony — modular, domain-centered behavior, clear separation from infrastructure, and practical SOLID guardrails without full hex/DDD layering |
Lightweight software principles
When to use
- Small feature or localized behavior change
- Few integrations and stable domain vocabulary
- Team wants speed with discipline, not full ports-and-adapters ceremony
Prefer superpowers:hex-infra when complexity, integrations, or long-term change pressure are high (see superpowers:selecting-implementation-architecture).
Core principles
- One thing per module — File or package does one job. Split when you cannot name the unit in one short phrase.
- Domain behavior in the center — Business rules live in named types or functions that do not import HTTP, DB, or SDKs. UI and IO call inward.
- Thin edges — Controllers, CLI handlers, and jobs validate and map; they do not own business rules.
- Explicit boundaries — Group by feature or bounded capability, not only by technical layer (
services/ soup).
- SOLID, lightly — Small interfaces where you have two implementations; inject or pass dependencies at edges; avoid god objects and wide public surfaces.
Practical checklist
Red flags
- Business rules scattered across controllers and "helper" utils
- Types named after persistence (
UserRow, OrderDto) driving domain flow
- Copy-paste validation or branching across multiple entrypoints
- "Just add another parameter" instead of a cohesive type or small port
With TDD
Always pair with superpowers:test-driven-development. Lightweight does not mean untested — it means fewer structural layers, not fewer tests.