Code Quality Overview
Introduction
At Builders International, code quality is not just a technical requirement—it's a core value that reflects our commitment to excellence, sustainability, and stewardship. High-quality code is maintainable, reliable, secure, and efficient. It serves our mission by ensuring our systems remain robust and adaptable as we scale our impact.
This documentation outlines our standards, expectations, and culture around code quality.
Why Code Quality Matters
Mission Impact
Poor code quality directly impacts our ability to serve communities effectively:
- Reliability: Bugs in production can disrupt critical services for vulnerable populations
- Security: Vulnerabilities can compromise sensitive beneficiary data
- Maintainability: Technical debt slows down feature development and bug fixes
- Performance: Inefficient code wastes resources and can make systems unusable in low-bandwidth areas
- Scalability: Well-designed systems can grow to serve more communities
Developer Effectiveness
High-quality code makes our team more effective:
- Onboarding: New developers can understand and contribute faster
- Debugging: Clear code with good tests makes issues easier to diagnose
- Confidence: Comprehensive tests allow developers to refactor without fear
- Collaboration: Consistent standards reduce friction in code reviews
- Joy: Working in a clean codebase is more satisfying and reduces burnout
Stewardship
We are stewards of donor resources:
- Cost Efficiency: Quality code reduces time spent on maintenance and firefighting
- Resource Utilization: Efficient code uses less infrastructure (lower cloud costs)
- Longevity: Well-documented systems remain useful beyond individual developers' tenure
Our Code Quality Culture
Collaborative, Not Combative
Code review is a collaborative learning process, not gatekeeping:
- Learning Together: Every PR is an opportunity for knowledge sharing
- Diverse Perspectives: Different backgrounds bring different insights
- Growth Mindset: We all have room to improve
- Psychological Safety: It's safe to make mistakes and ask questions
- Shared Ownership: We all own the codebase together
See our detailed Code Review Process for more.
Quality is Everyone's Responsibility
Code quality is not just the responsibility of senior developers or designated reviewers:
- Authors: Write the best code you can, ask for help when needed
- Reviewers: Provide thoughtful, actionable feedback
- Team Leads: Model good practices and create space for quality work
- Product: Allow time for technical excellence in sprint planning
Test-Driven Development
We practice TDD because it leads to better design and higher confidence:
- Red-Green-Refactor: Write failing test → make it pass → improve design
- Comprehensive Coverage: Aim for >90% code coverage, require >80%
- Test First: Writing tests first improves API design
- Fast Feedback: Tests catch regressions immediately
- Living Documentation: Tests document expected behavior
See our Testing Standards for detailed guidance.
Core Principles
1. Clarity Over Cleverness
Code is read far more often than it's written. Optimize for readability:
// Bad: Clever but hard to understand
const r = d.filter(x => x.s === 'a').map(x => x.n);
// Good: Clear and self-documenting
const activeUserNames = users
.filter(user => user.status === 'active')
.map(user => user.name);
2. Simple Over Complex
Avoid over-engineering. Build what you need today, not what you might need tomorrow:
# Bad: Over-engineered for current needs
class UserFactoryBuilder:
def __init__(self):
self.strategies = {}
def register_strategy(self, name, strategy):
self.strategies[name] = strategy
def build(self, strategy_name, **kwargs):
return self.strategies[strategy_name](**kwargs)
# Good: Simple and sufficient
def create_user(name: str, email: str) -> User:
return User(name=name, email=email)
3. Secure by Default
Security is not optional. Every developer must understand basic security principles:
- Input Validation: Never trust user input
- Authentication: Verify identity before granting access
- Authorization: Check permissions for every protected resource
- Data Protection: Encrypt sensitive data at rest and in transit
- Secrets Management: Never commit credentials to version control
See security best practices in Best Practices.
4. Performance Awareness
Not every line needs to be optimized, but be aware of performance implications:
- Profile Before Optimizing: Measure don't guess
- Big-O Awareness: Understand algorithmic complexity
- Database Efficiency: Use appropriate indexes, avoid N+1 queries
- Resource Limits: Consider memory and CPU constraints
- User Experience: Performance is a feature, especially in low-bandwidth areas
5. Documentation Standards
Good documentation is part of code quality:
- Code Comments: Explain why, not what (the code shows what)
- README Files: Every project needs setup and architecture docs
- API Documentation: Document public interfaces clearly
- Decision Records: Capture significant architectural decisions
- Inline Examples: Show how to use complex functions
// Bad: Comment explains what (redundant)
// Get user by ID
function getUserById(id: string) { ... }
// Good: Comment explains why (adds value)
// Cache user lookups because user data changes infrequently
// and is accessed on every request
function getUserById(id: string) { ... }
Quality Standards
Code Review Requirements
All code must be reviewed before merging:
- Minimum 1 Approval: At least one team member must approve
- Platform Team Review: Infrastructure changes need platform team approval
- Security Review: High-risk changes need security review
- Breaking Changes: Must be discussed and documented
See detailed requirements in Code Review Process.
Testing Requirements
All production code must have tests:
- Unit Tests: >80% coverage required, >90% preferred
- Integration Tests: Critical paths must have integration tests
- E2E Tests: User-facing features need end-to-end tests
- CI Integration: All tests run on every PR
- No Flaky Tests: Tests must be deterministic
See comprehensive guidance in Testing Standards.
Linting and Formatting
Automated tools enforce consistent style:
- JavaScript/TypeScript: ESLint + Prettier
- Python: Black + Pylint/Flake8
- Go: gofmt + golangci-lint
- CI Enforcement: Linting failures block PRs
- Pre-commit Hooks: Catch issues before pushing
Security Standards
Security is non-negotiable:
- OWASP Top 10: All developers must understand common vulnerabilities
- Dependency Scanning: Automated vulnerability scanning in CI
- Secrets Management: Use environment variables or secret managers
- Code Scanning: Static analysis tools catch security issues
- Security Headers: Appropriate headers on all HTTP responses
Language-Specific Standards
We maintain detailed best practices for each language:
TypeScript/JavaScript
- Strict TypeScript configuration
- No
anytypes without justification - Functional programming patterns preferred
- React best practices for frontend
Python
- PEP 8 compliance
- Type hints on function signatures
- Virtual environments for all projects
- Black for consistent formatting
Go
- Standard Go formatting (gofmt)
- Interface-based design
- Proper error handling (never ignore errors)
- Context for cancellation
See complete details in Best Practices.
Integration with Other Standards
Code quality doesn't exist in isolation:
Infrastructure Standards
- IaC Quality: Infrastructure code follows same quality standards
- Configuration: Use validated, tested configurations
- Monitoring: Quality code includes observability
See Infrastructure Documentation.
CI/CD Integration
- Automated Testing: Every CI pipeline runs full test suite
- Quality Gates: PRs blocked on test failures, linting errors, low coverage
- Deploy Confidence: Good tests enable confident deployments
See CI/CD Documentation.
Measuring Code Quality
We track key metrics to maintain standards:
Coverage Metrics
- Unit Test Coverage: Target >90%, require >80%
- Integration Coverage: Critical paths must be covered
- Coverage Trends: Coverage should trend upward over time
Code Quality Metrics
- Linting Violations: Should be zero (enforced in CI)
- Complexity Scores: Monitor cyclomatic complexity
- Duplication: Keep code duplication minimal
- Dependency Health: Keep dependencies up to date
Review Metrics
- Review Time: First response within 4 hours, complete within 24 hours
- Review Thoroughness: Multiple rounds of feedback when needed
- Approval Rate: Not a vanity metric, rejections are healthy
Security Metrics
- Vulnerability Count: Active CVEs should trend to zero
- Dependency Age: Keep dependencies reasonably current
- Security Review Coverage: High-risk changes get security review
Continuous Improvement
Code quality is a journey, not a destination:
Regular Retrospectives
- Team Retrospectives: Discuss quality issues and solutions
- Post-Mortems: Learn from production incidents
- Standard Updates: Evolve standards based on experience
Learning Culture
- Lunch and Learns: Share knowledge across the team
- Code Reading Sessions: Learn from each other's code
- External Resources: Encourage conference talks, courses, books
Refactoring Time
- Tech Debt Tracking: Maintain a backlog of known issues
- Refactoring Sprints: Dedicate time to improving existing code
- Boy Scout Rule: Leave code better than you found it
Getting Started
New to our code quality standards? Start here:
- Read This Overview: Understand our philosophy and principles
- Review Testing Standards: Learn our testing requirements and patterns
- Study Best Practices: Familiarize yourself with language-specific standards
- Practice Code Review: Start reviewing PRs with feedback from senior developers
- Ask Questions: Use team channels to clarify anything unclear
Common Questions
Q: What if I don't have time to write tests?
A: Writing tests actually saves time by catching bugs early and enabling confident refactoring. If you truly don't have time for tests, the feature is not ready to ship. Discuss timeline constraints with your team lead.
Q: Can I skip code review for small changes?
A: No. Even small changes benefit from review. Typo fixes and documentation updates can be approved quickly, but should still be reviewed.
Q: What if I disagree with a reviewer's feedback?
A: Discuss respectfully. Reviewers are usually right, but not always. If you can't reach consensus, involve a team lead or senior developer.
Q: How do I balance quality with speed?
A: Quality and speed are not opposites. Good tests and clear code enable faster development over time. Short-term pressure should not compromise long-term quality.
Q: What if our codebase doesn't meet these standards yet?
A: Apply the Boy Scout Rule: leave code better than you found it. Gradually improve quality with each change. Schedule dedicated refactoring time for larger improvements.
Additional Resources
- Testing Standards - Comprehensive testing guidance
- Code Review Process - Detailed review requirements
- Best Practices - Language-specific standards
- Infrastructure Standards - Infrastructure code quality
- CI/CD Documentation - Automated quality checks
Summary
Code quality at Builders International means:
- Collaborative Culture: Learning together through code review
- Comprehensive Testing: TDD with >80% coverage
- Clear Documentation: Code and systems are well-documented
- Security Awareness: OWASP principles applied consistently
- Performance Mindset: Efficient code that serves users well
- Continuous Improvement: Always learning and refactoring
Quality code is our gift to future developers, our users, and the communities we serve.