I spent two decades advocating ATDD from the first line of code, because that was how you kept the cost of change low. AI agents changed the economics: I now start with days of violent prototyping, and only add e2e guardrails once I know what behavior is worth protecting.
A hiring process exists to approximate what it's like to work with a person. AI agents changed how candidates write code, so I now let them use agents in pair-programming interviews; the signals I read stayed almost the same, and the project and system design questions survived untouched.
LLMs collapse the cost of writing single-use software, making bespoke viable where reuse used to win by default. Here's the framework for when bespoke beats reuse, when reuse still wins, and the real question underneath both.
A guest post from Claude Code: the brief Shai gave, the places one of us overruled the other, how the Wix-to-Astro migration actually went, and what shipped.
AI Agents are just like human contractors only faster; to make them work at scale and in a stable manner, you need to use deterministic, executable checks like tests, compilers, linters, etc - otherwise you're doing no better than prayer.
There’s a particular kind of joy in seeing seeds you planted years ago take root. Watching an engineering organization grow over the course of several years, and seeing ideas we introduced become part of its everyday rhythm, have been some of the most gratifying parts of my work. This is the story of how a small engagement with HoneyBook evolved into a multi-year partnership that shaped everything…
In the final post of this series, we’ll cover how applications where both the frontend and the backend are built with Javascript can benefit from a novel approach to testing: in-process, JSDOM-based acceptance tests that drive the UI, but incorporate a backend that uses memory fakes for speed and determinism. The benefits are substantial: with this type of tests, we do not need to mock or fake the…
In the fast-paced world of software development, change is the only constant. User needs evolve, new technologies emerge, and market conditions shift. In this environment, rigid, inflexible code is a liability. It's like a brittle sculpture that shatters under pressure. To build software that thrives in the face of change, we need to embrace a different mindset. We need to think of code not as a…
Update, January 2022:Shortly after publishing this post the Mac failed to connect to the display. Through a friend who works at Apple I got to a person who maintains the Thunderbolt firmware on Macbooks, and apparently the problem was caused by a combination of two issues; the first issue being a physical breakage in the Thunderbolt cable affecting only half of the wires inside, and the second…
Written 56 years ago, the Litany Against Fear plays an important part in the novel Dune, allowing the protagonist to overcome his crippling feelings and go through difficult ordeals. Recently it dawned on me that it could be just as effective - and just as true - when dealing with fear of change in software systems. Let's go over the litany line by line and consider its meaning and implications.I…
For the past few months I've been working with a startup building a mobile app using #ReactNative. I last used #React back in 2016, and my most recent mobile development was in the joyful J2ME days of 2007, so I was a bit hesitant to dive into this codebase. Usually, I find my way around new codebases and technologies by #pairprogramming with an experienced colleague, but with COVID-19 and the…
We spend most of our time maintaining software. Writing features we might need in the future is not only a waste of time, it makes your software harder to maintain.
This blog post was originally published in the Orbs Engineering blog in 2018.My previous post described how the Go reference implementation of the Orbs Network blockchain protocol used Hexagonal Architecture to facilitate upfront design, while allowing the inner design of components inside the system to emerge via TDD. We left off with a promise to discuss Component Tests, as well as elaborating…
When we started coding the Orbs reference implementation in the Go programming language, we had several guidelines in mind: The code must be written outside-in using TDD The code must have bounded contexts, expressed as interfaces generated f