August 4, 2023


Don’t make everybody busy from day one. Use the first stages of a software project to facilitate mob programming sessions and create a shared understanding.

Embrace some early duplication. Use the first few weeks to explore the problem space and try different approaches. Removing duplication is often easier than dealing with flawed architectures.

Optimize for short feedback loops. Trunk-based development, test-driven development, or continuous deployment are techniques that guide the team toward this objective.

For your initial test suite, optimize for confidence rather than speed (you can always fix performance later). That usually means creating more acceptance/integration tests than unitary ones. Also, tests of higher granularity levels help to develop test-friendly software systems.

When writing documentation, use how-to guides (how to execute a background job, how to log analytics events) and architecture decision records (so everybody can understand the WHY of certain design decisions).

Tackle the tasks with the most uncertainty first.

Simple !== Easy, but beware, they are often confused (perhaps because simple solutions are harder to design and implement).

Good software design always pays off.

Slice the work wisely. Rather than slicing by technical layers (for example, creating one task for front-end work and another for back-end work), use slices that make business sense and provide value (i.e., the minimum viable feature). Vertical slices enable shorter feedback loops and reduce integration problems.

If using a pull-requests-based workflow, avoid the notion of one feature = one pull request. Use stacked pull requests to generate smaller reviewable units.

Keep your options open, especially at the beginning. Use the Last Responsible Moment technique to drive your decision-making process.