Simplicity first: Code should be simple to read, simple to understand, and simple to change.
Startup agility: Write clear, working code first. Optimize performance and add robustness only when profiling shows bottlenecks or when you have real scale.
- Write code for humans, not just compilers
- Use clear, descriptive names for variables, functions, and classes
- Prefer explicit code over implicit magic
- Avoid premature optimization
- Keep functions small and focused on one task
- Limit function complexity (cyclomatic complexity)
- Prefer composition over large classes
- Extract methods when functions grow too large
- Code should explain itself through good naming
- Use comments to explain "why", not "what"
- Remove commented-out code
- Keep comments current with code changes
- Follow consistent project structure across the monorepo
- Group related code together
- Separate concerns clearly (UI, business logic, data access)
- Use standard patterns and conventions
- Minimize dependencies
- Keep dependencies up to date
- Remove unused dependencies
- Prefer well-maintained, standard libraries
- Define clear module boundaries
- Minimize coupling between modules
- Maximize cohesion within modules
- Use interfaces to define contracts
- Write tests that verify behavior, not implementation
- Prefer integration tests over unit tests for business logic
- Test the happy path and critical error cases
- Keep tests simple and maintainable
- Tests should be readable and self-documenting
- Use descriptive test names that explain what they verify
- One assertion per test when possible
- Avoid test interdependencies
- Aim for meaningful coverage, not 100%
- Focus on critical paths and business logic
- Don't test framework code or trivial getters/setters
- Use coverage to find untested code, not as a goal
- Review for correctness, clarity, and simplicity
- Check that code follows team conventions
- Verify tests are appropriate and passing
- Ensure documentation is updated
- Keep reviews small and focused
- Provide constructive, actionable feedback
- Approve when code is good enough, not perfect
- Use reviews as learning opportunities
- Refactor in small, incremental steps
- Refactor when you understand the code better
- Remove dead code and unused features
- Simplify before adding new functionality
- Have tests before refactoring
- Refactor in separate commits from features
- Use automated refactoring tools when available
- Verify behavior hasn't changed after refactoring
- Provide clear, actionable error messages
- Include context in error messages
- Log errors with sufficient detail for debugging
- Handle errors at the appropriate level
- Fail fast when possible
- Use exceptions for exceptional cases
- Don't swallow errors silently
- Make error recovery paths clear
- Write clear code first, optimize when needed
- Measure before optimizing - always profile first
- Optimize bottlenecks, not everything
- Consider performance in design, but don't over-engineer
- Ship working code - optimize later when you have data
- After Profiling: Only optimize code that profiling shows is slow
- User Impact: When performance issues affect real users
- Scale: When you have significantly more users/data than before
- Business Impact: When performance affects business metrics
- Measured Bottlenecks: When monitoring shows actual problems
- Profile First: Use profiling tools to find real bottlenecks
- Measure Baseline: Establish performance baselines before changes
- Optimize Incrementally: Make one optimization at a time
- Validate Impact: Measure after each optimization
- Document Why: Record why optimizations were needed
- Balance performance with maintainability
- Document performance-critical code
- Use profiling to find real bottlenecks
- Avoid premature optimization
- Don't sacrifice code clarity for theoretical performance gains
- Don't optimize code that isn't a bottleneck
- Don't optimize without profiling first
- Don't add complexity for theoretical performance gains
- Don't optimize for scale you don't have
- Don't sacrifice readability for micro-optimizations
- Document public APIs clearly
- Use code examples in documentation
- Keep documentation current with code
- Document design decisions and rationale
- Maintain clear README files for each project
- Document setup and development processes
- Keep documentation simple and focused
- Update documentation as code changes
- Use automated formatting tools
- Follow consistent style guides
- Configure linters and formatters consistently
- Don't debate style - automate it
- Follow language idioms and best practices
- Use language features appropriately
- Avoid anti-patterns for the language
- Keep up with language evolution
- Over-engineering and premature abstraction
- Copy-paste code instead of extracting commonality
- Ignoring compiler/linter warnings
- Writing tests that test the test framework
- Optimizing before measuring
- Complex solutions when simple ones work
- Optimizing code that isn't a bottleneck
- Adding robustness "just in case"
- Enterprise patterns without enterprise problems
- Micro-optimizations that hurt readability