Technical Blog

Ideas on building better software

A collection of articles covering software architecture, distributed systems, lean methodologies, and team dynamics — drawn from real-world experience.

Abstract watercolour composition with overlapping translucent circles in warm amber, soft teal, and muted grey tones, evoking resonance and connection.

Empathetic Software Development with the Business Model Canvas

Exploring how the Business Model Canvas can guide software teams toward more empathetic, business-aligned decision-making — connecting code to customer outcomes.

Lean Business Architecture

Continuous Delivery with Thoughtworks GO and Docker

A practical walkthrough of setting up a continuous delivery pipeline using Thoughtworks GO and Docker containers for repeatable, reliable deployments.

Continuous Delivery Docker DevOps

A Strategy for Building Software Teams

Lessons learned from assembling and nurturing effective engineering teams — covering hiring, culture, and the rhythms that sustain high performance.

Teams Kanban Lean

Building Distributed Systems with Akka

Diving into Akka clustering and actor-based concurrency for resilient, scalable distributed systems on the JVM.

Scala Akka Distributed Systems

Topics I write about

A broad set of interests, one blog

Scala

Lean

Architecture

Kanban

Continuous Delivery

Business Metrics

Distributed Systems

Team Dynamics

Building software is as much about understanding people as it is about understanding code. An empathetic developer recognises that every line written ultimately serves human users, colleagues, and future maintainers. This perspective shifts the focus from technical purity toward practical outcomes that genuinely improve workflows and experiences. It means designing systems that are not only elegant in structure but also intuitive to interact with and straightforward to modify. Empathy fuels better collaboration within teams, encouraging open feedback loops and a culture where questions are welcomed rather than dismissed. When developers prioritise understanding the motivations and pain points of those around them, the resulting software tends to be more resilient, more useful, and more aligned with real-world needs.

Software architecture benefits greatly from a lean, iterative mindset. Rather than attempting to predict every future requirement upfront, experienced teams build systems that can evolve gracefully through continuous feedback and incremental improvements. This approach reduces the risk of over-engineering while keeping delivery cycles short and predictable. Distributed systems, in particular, demand careful thought about boundaries, communication patterns, and failure modes. Embracing functional programming principles often helps manage complexity by making state changes explicit and side effects predictable. The goal is not architectural perfection from day one but rather a structure that accommodates change without requiring constant rewrites, allowing the team to respond to new insights as they emerge throughout the development process.

Team dynamics play a decisive role in how effectively software gets built and delivered. A group of skilled individuals does not automatically form a high-performing team unless there is psychological safety, clear communication, and shared ownership of outcomes. Agile methodologies provide useful frameworks for organising work, but the real value comes from the principles behind them: regular reflection, continuous adjustment, and genuine collaboration. Developers thrive when they have room to experiment, fail safely, and learn from mistakes without fear of blame. Leaders who cultivate an environment where every voice is heard tend to unlock more creative solutions and stronger commitment to shared goals. Ultimately, healthy team culture is the engine that drives consistent, high-quality delivery.

Continuous improvement is a mindset that extends beyond code into every aspect of a developer's practice. Refactoring, test-driven development, and regular retrospectives are all tools that support this philosophy. Writing tests first not only catches defects early but also clarifies intent and encourages cleaner design. Metrics and feedback loops help teams see where bottlenecks occur and which changes actually move the needle on performance or user satisfaction. The pursuit of better outcomes never truly ends, and that is precisely what makes software development such a compelling field. Each project brings new challenges that sharpen skills and deepen understanding. Developers who embrace this cycle of learning and adaptation tend to build more robust systems and enjoy more fulfilling careers along the way.

The tools and technologies a developer chooses reflect deeper values about how software should be created and maintained. Some prefer the reliability and ecosystem of the JVM, while others gravitate toward the simplicity of Linux-based environments and functional languages. These preferences are not arbitrary; they stem from experiences with different paradigms and the specific demands of past projects. What matters most is not which stack wins an argument but whether the chosen tools help the team deliver value sooner and more sustainably. Reading widely, exploring diverse approaches, and staying curious about emerging patterns all contribute to a richer understanding of the craft. A well-rounded developer draws from multiple traditions, adapting their approach to fit each unique context rather than rigidly adhering to a single doctrine.

Also check out

Book Reviews

I read widely across .NET, Agile, DDD, TDD, distributed systems, psychology, and more. See what I've been learning.

Browse Books