Skip to main content

Development Practices Overview

Development practices are the habits, techniques, and processes that software engineers use daily to write better code, collaborate effectively, and deliver value consistently. This section covers practices that apply across all platforms, languages, and frameworks.

What Are Development Practices?

Development practices differ from architecture (high-level system design) and from language/framework-specific techniques. Instead, they represent:

  • Quality habits: How we ensure code is maintainable, accessible, and performs well
  • Workflow techniques: How we approach debugging, refactoring, and managing dependencies
  • Team standards: Shared expectations that enable collaboration

Good development practices compound over time - small consistent improvements lead to dramatically better outcomes.

Why Practices Matter

Poor practices create technical debt - the gap between current code quality and desired quality. Like financial debt, technical debt compounds with interest, making future changes progressively harder.

Conversely, good practices create technical leverage - infrastructure and habits that make future work easier.

Core Development Practices Covered

Accessibility

Building software that works for everyone, including people with disabilities. Accessibility isn't just ethical - it's often legally required and expands your user base.

Key principles:

  • Perceivable: Information and UI components must be presentable to users in ways they can perceive
  • Operable: UI components and navigation must be operable
  • Understandable: Information and UI operation must be understandable
  • Robust: Content must be robust enough to be interpreted by a wide variety of user agents

When to apply: Every user-facing application (web, mobile, desktop)

Internationalization (i18n)

Designing software to support multiple languages, regions, and cultures without engineering changes.

Key concerns:

  • Text translation and locale-specific formatting
  • Date, time, number, and currency formats
  • Right-to-left (RTL) language support
  • Cultural considerations (colors, symbols, imagery)

When to apply: Any application with potential international users, or even multi-regional domestic users

Refactoring

Improving code structure without changing its external behavior. Refactoring is how we pay down technical debt and keep code maintainable as requirements evolve.

Key principle: Small, safe, incremental changes. Never refactor and add features simultaneously.

When to apply: Continuously as part of feature development, not as separate "cleanup" projects

Debugging

Systematically identifying and fixing defects. Debugging is a skill that improves with deliberate practice.

Scientific method approach:

  1. Observe the problem
  2. Form a hypothesis
  3. Test the hypothesis
  4. Analyze results
  5. Repeat or fix

When to apply: When behavior doesn't match expectations - during development, testing, and production support

Code Quality Metrics

Objective measurements of code quality that guide improvement efforts and prevent regression.

Key metrics:

  • Code coverage (with caveats)
  • Cyclomatic complexity
  • Code duplication
  • Maintainability index
  • Technical debt ratio

When to apply: Continuously through automated tooling in CI/CD pipelines

Dependency Management

Controlling what external libraries your project uses, keeping them up to date, and managing security vulnerabilities.

Key concerns:

  • Choosing dependencies wisely
  • Keeping dependencies updated
  • Security scanning and remediation
  • Managing transitive dependencies

When to apply: At project start and continuously throughout development

Feature Flags

Decoupling deployment from release by hiding incomplete features behind runtime toggles. Enables safer deployments, gradual rollouts, and A/B testing.

Types:

  • Release flags: Short-lived, enable/disable new features
  • Experiment flags: A/B tests and controlled rollouts
  • Operational flags: Circuit breakers, performance tuning
  • Permission flags: Role-based feature access

When to apply: Complex features, risky changes, features requiring gradual rollout

The Practice Mindset

Continuous Improvement

Development practices aren't about perfection - they're about consistent progress:

  1. Identify pain points: What slows you down? Where do bugs come from?
  2. Learn techniques: Study practices that address those pains
  3. Apply incrementally: Adopt new practices one at a time
  4. Measure impact: Did the practice help? Adjust accordingly
  5. Share knowledge: Help teammates adopt effective practices

Balance Pragmatism and Idealism

Perfect code doesn't exist. Every practice involves trade-offs:

  • Accessibility adds development time but expands your audience
  • Internationalization upfront is cheaper than retrofitting later
  • Refactoring improves maintainability but doesn't add features
  • Code quality metrics guide improvements but can be gamed
  • Feature flags enable flexibility but add complexity

Make conscious decisions about when to invest in quality practices based on:

  • Risk: What's the cost of defects in this code?
  • Longevity: Will this code exist for years or weeks?
  • Collaboration: How many people will work on this?
  • Compliance: Are there legal/regulatory requirements?

Automate What You Can

Manual practices are inconsistently applied. Automation ensures practices are followed:

  • Linting: Enforce code style automatically (see Linting guidelines)
  • Formatting: Auto-format code on save or commit
  • Testing: Run tests in CI/CD (see CI Testing)
  • Security scanning: Automated dependency and code vulnerability checks
  • Accessibility testing: Automated a11y checks in build pipeline

Reserve human effort for practices that require judgment - code review, design decisions, complex debugging.

Practice Integration

Development practices don't exist in isolation. They integrate with:

With Code Review

Code review is where practices are taught and enforced:

  • Reviewers check for accessibility issues
  • Identify refactoring opportunities
  • Verify dependencies are appropriate
  • Ensure internationalization is considered

With Testing

Testing validates that practices are effective:

  • Accessibility testing verifies WCAG compliance
  • Integration tests catch refactoring regressions
  • Dependency updates are validated through test suites
  • Feature flags are tested in multiple states

With CI/CD

Pipelines automate practice enforcement:

  • Fail builds on accessibility violations
  • Run quality metrics and enforce thresholds
  • Check for vulnerable dependencies
  • Validate internationalization completeness

With Definition of Done

DoD formalizes practice expectations:

  • Features must meet accessibility standards
  • Code must meet quality thresholds
  • Dependencies must be approved and scanned
  • Feature flags must be documented

Practice Ownership

Individual Responsibility

Every engineer owns the quality of their code:

  • Write accessible code by default
  • Refactor as you go ("Boy Scout Rule")
  • Debug systematically, not randomly
  • Choose dependencies thoughtfully

Team Standards

Teams establish shared practices through:

  • Coding standards documents: Team-specific conventions (see Ways of Working)
  • Code review checklists: Common things to verify
  • Automated tooling configurations: Shared linter/formatter configs
  • Team retrospectives: Continuous practice improvement

Organizational Enablement

Organizations support good practices by:

  • Providing time: Include quality work in estimations
  • Providing tools: License quality, security, and accessibility tools
  • Providing training: Offer learning resources and workshops
  • Measuring outcomes: Track quality metrics and incidents

Measuring Practice Adoption

How do you know if practices are working?

Lead Indicators (Predictive)

  • Code review turnaround time
  • Test coverage trends
  • Number of accessibility issues found pre-production
  • Refactoring frequency
  • Dependency update frequency

Lag Indicators (Outcome)

  • Production incident frequency
  • Bug escape rate (bugs found in production vs. testing)
  • Time to resolve bugs
  • Accessibility compliance audit results
  • Customer-reported issues

Track both types. Lead indicators let you adjust before problems occur; lag indicators validate your efforts.

Getting Started

For New Projects

Build quality in from the start:

  1. Set up automation: Linting, formatting, testing, security scanning
  2. Define standards: Agree on practices before writing production code
  3. Configure tooling: Set up accessibility checkers, quality gates
  4. Document practices: Create a team README with conventions
  5. Establish review culture: Make code review a learning opportunity

For Existing Projects

Improve incrementally:

  1. Assess current state: What practices exist? What's missing?
  2. Prioritize pain points: Where do bugs come from? What slows development?
  3. Pick one practice: Don't try to fix everything at once
  4. Apply to new code: Don't rewrite everything; improve as you go
  5. Measure improvement: Did the practice help? Adjust accordingly

Common Pitfalls

Cargo Cult Practices

Adopting practices because "best practices say so" without understanding why. Every practice has trade-offs - understand the costs and benefits for your context.

Example: Achieving 100% code coverage doesn't guarantee quality if tests are poorly written.

Practice Theater

Following the letter of practices without the spirit - checking boxes without achieving outcomes.

Example: Running accessibility scanners but ignoring the findings, or refactoring code that works perfectly fine instead of addressing real pain points.

Perfectionism Paralysis

Refusing to ship until every practice is perfectly applied.

Example: Delaying a feature for weeks to achieve "perfect" accessibility when incremental improvement would serve users better.

Practice Inconsistency

Applying practices to some code but not others, creating a fragmented codebase.

Example: New features follow internationalization practices, but old code doesn't, making global rollout impossible.

Further Learning

Books:

  • Refactoring: Improving the Design of Existing Code by Martin Fowler (2018)
  • The Pragmatic Programmer by David Thomas & Andrew Hunt (2019)
  • Clean Code by Robert C. Martin (2008)
  • Working Effectively with Legacy Code by Michael Feathers (2004)

Online Resources:

Practice:

  • Participate actively in code reviews - both giving and receiving feedback
  • Dedicate time to learning one practice deeply each quarter
  • Share learnings with your team through demos or documentation
  • Track quality metrics and celebrate improvements