Thoughts on Building Good (Software) Products Link to heading

Creating a product that delights customers is typically a tricky and non-deterministic process. Lots can go wrong in the many steps between getting the raw idea onto a whiteboard and unveiling a finished product to customers, and the path of development is never a straight line. This is particularly true in startups, where – by definition – your product is breaking new ground, and there is no clear map and maybe even no compass to follow.

Typical Challenges Link to heading

Typical challenges in software product creation include:

  • broken telephone
    • ill-defined or drifting business requirements and goals
    • unclear or missing communication with and between developers
    • poor or non-existent UX designs and technical designs
    • requests go unseen in noisy communication channels
    • people just plain forget to communicate
  • limited ability to get feedback
    • faulty or missing customer feedback loop
    • product defects only found through manual inspection
    • insufficient ability to observe and debug systems in production
  • tools that are a poor fit for the job at hand (e.g. design tools, programming languages, platforms, APIs. And be warned, this is a religious issue!)
  • excessive time pressure
  • insufficient or excessive resources (people, money) for the job at hand

The result can be misalignment between development work and business value (building the wrong stuff), poor design decisions which have bad downstream ripple effects, wrongly-calibrated expectations on product capabilities and delivery timing, frustrated employees, and disappointed customers whose expectations are not being met. And when the time pressures are too high, product quality can also suffer due to cutting corners.

Useful Techniques Link to heading

Here are some techniques that have worked for me, both in startup product teams and in large product teams. I’ve organized these into three types of product activities – planning, development, and operations – although in reality the three activity areas are intermingled and continuous, especially in smaller and agile teams where people wear multiple hats.

Practices that help with planning activities Link to heading

  • regularly express and update your business strategy, objectives and priorities
  • create UX designs and style guidelines to help plan visual elements
  • create architectural designs and adopt coding conventions to help plan software systems
  • regularly align technical work items and business objectives
  • talk to customers early and often, collecting feedback on the work while it is in planning and development
  • sequence and prioritize work so as to reduce risk as early as possible
  • eliminate YAGNI work (You Ain’t Gonna Need It, i.e. low-value work)
  • strive for a consistent planning, development and delivery cycle
  • break work into small batches whenever possible
  • plan work so that shaving scope is possible when necessary; see the “appetite” concept in Shape Up
  • only commit to fixed delivery dates for things that are truly deadline-driven
  • foster a company-wide understanding of the product planning Iron Triangle and acceptance of its implications

Practices that help with development activities Link to heading

  • break work into small batches whenever possible
  • choose design and development tools that enable team members to implement their ideas with high fidelity and efficiency
  • strengthen your ability to detect and avoid defects as early as possible
    • integrate automatic linters and formatters in code editing tools
    • write and run tests as part of the regular coding workflow
    • increase test code coverage for complex code
    • increase test code coverage for any code that breaks in production
    • review code prior to publishing it (for learning, and quality improvement)
    • adopt tools and processes to measure and boost code quality

Practices that help with operational activities Link to heading

  • choose deployment platforms that strike the right balance between power and ease of use for the product/project you’re working on. Example: full-featured systems like AWS or Azure versus convenience-oriented systems like Heroku or Vercel. They each have their place.
  • if you can afford it, create a staging environment that mirrors production, with fake data
  • pursuse fast, easy, and frequent deployments
  • add monitoring systems e.g. for exception and uptime tracking
  • separate operational communication channels from planning and development, so as to reduce noise and help people focus
  • make developers responsible for both building and operating the system

There is no Magic Bullet… Link to heading

…but there are many little pieces worth trying.

I’ve found that incrementally adding supports like these help product teams increase efficiency and increase confidence that their actions will result in incremental improvements to a high-quality product.

Of course, this methodology and collection of techniques is not a fit for every team and project. And regardless of your methodology you need “just enough”; too much process and tooling and the team drowns under the weight; too little, and product progress is choppy because quality problems cause two-steps-forward, one-step-back situations. But it’s great when you can find a workable mix of techniques like this, and it really feels fantastic working in a team that is progressively mastering the craft of building great products.

See also Link to heading

On planning: