- Clarity > cleverness. Explicit > implicit. Maintainability first.
- Use standard library before adding dependencies.
- Make it work → make it right → make it fast.
- Ship practical solutions over theoretical perfection.
- Check standard library/existing code first
- Start with straightforward linear logic
- Extract abstractions only after 3rd duplication (Rule of Three)
- Question requirements before adding complexity
- Optimise only with profiling data
- Naming: Descriptive, self-explanatory
- Control flow: Early returns over deep nesting
- Functions: Single responsibility, one thing well
- Composition over inheritance
- Coupling: Minimise cross-module dependencies
- Structure: Start flat, add hierarchy only when needed
- Direct function calls before events/messaging
- Can standard library/existing deps solve this?
- Every dependency = maintenance + security risk
- Prefer: mature, active, focused libraries over frameworks
- Don't add unless explicitly needed
- Expected errors: Use Result types/error values when idiomatic
- Unexpected errors: Let bubble to logging boundary
- Messages: Clear, actionable, with context (no secrets/PII)
- User-facing: Never expose stack traces/internals
- Logging: Include IDs, types, key inputs for debugging
- Correctness first, then optimise bottlenecks with metrics
- Consider Big-O before micro-optimisations
- Comment non-trivial optimisations with rationale
- Test public interfaces and observable behaviour
- Skip: Trivial assertions, "does not crash" tests
- Priority: 1) Happy paths 2) Edge cases 3) Failure modes
- One behaviour per test with clear names
- Structure: Arrange → Act → Assert
- Mock I/O/external services, not pure logic
- Keep tests fast
- Comments: Explain why, not what
- README: Purpose, setup, usage, key concepts
- APIs: JSDoc/docstrings with examples
- Keep in sync; don't document non-existent features
- Validate all external input
- Use least privilege
- No hardcoded secrets (use env/secret manager)
- Avoid unsafe defaults (verify: false, wide CORS, eval)
- Check dependency vulnerabilities
- Structured logging with correlation IDs
- Make errors traceable
- Avoid magic/hidden side effects
- Incremental improvements over rewrites
- Add characterisation tests before changes
- Leave code better than found: refactor, clarify, reduce duplication