Hey there! Early every year we publish a list of techniques and tools you should consider in your new year resolutions.
It’s a list of recommended items, each with my own commentary about why you should add it to your arsenal. This year we are kinda late, but hopefully in time for your Q2 planning!
So how do we pick these items?
Most of them come from good conversations with smart tech leaders I know. These happen in the community, over the podcast, and in my network of friends. I also have a small set of publications I trust, from which I snipe material — most notably the Thoughtworks Radar, which pretty much inspires this work.
With respect to previous years, this time we will focus less on tools and more on core techniques — that is, practices that almost any engineering team can apply.
We will explore ten of them, and for each we will explain why it matters, why now, and recommended tools / resources to implement it.
Let’s dive in!
1) 🚚 Continuous Deployment
There is a lot of confusion about the differences between continuous integration, continuous delivery, and continuous deployment, so here is a recap:
🥉 Continuous Integration — means that pushing new code into a shared repository triggers an automated build & testing process. Example: a dev opens up a PR; automated tests run in CI; if tests pass, the code can be merged into the main branch.
🥈 Continuous Delivery — means that code on the main branch can be deployed at any time — i.e. it is always in a deployable state. Example: code passes CI tests; it is automatically deployed to a staging environment; a human manually approves the release to production.
🥇 Continuous Deployment — means that every change that passes automated tests gets automatically deployed to production.
So, continuous deployment extends continuous delivery by removing manual approvals. This enables faster feedback loops and ensures code changes don’t get stale or batched in pre-prod stages like staging.
Small + frequent changes vastly reduce risk and improve developer productivity because there fewer handoff steps.
Also, deploying code doesn’t necessarily mean to release it! In fact, you should decouple the two things with the next technique 👇
2) 🐥 1% Canary
I love the name 1% canary — which I stole from Thoughtworks. This is the practice of rolling out new software to a super small sample of users, to reduce risk and do additional QA.
This sample can be arbitrarily small: it can be beta users, a selected group of testers, or even just people on your team.
The point is to move the final QA stage to production, so that you skip an intermediate step, plus you make sure you are testin gon the real thing, instead of a replica.
You can implement this by using feature flags and feature management workflow tools. We covered this in various previous articles:
3) 🗺️ Domain-Driven Design
Ok this is not exactly new! DDD has been around for more than 20 years, and has only grown in importance year after year.
Most recently, I believe we got to an inflection point that turned DDD from simply excellent to inevitable for most engineering teams — because of AI.
Why is that? Let’s take a step back and define what DDD is about.
At its core, DDD is about organizing software around the business domain, rather than technical concerns. It does so through various devices, like:
🗣️ Ubiquitous Language — teams create a shared vocabulary that both developers and business people use to avoid misunderstandings.
📐 Bounded Contexts — identifying different parts of the systems so that they have clear, well-defined responsibilities and relationships.
🔀 Context Mapping — describe the types of relationships between bounded concepts and teams.
Giving an exhaustive description of DDD is out of the scope of this piece (and we would need an entire book) but you get the idea.
The key part here is that DDD focuses on creating clarity about the business domain and its moving parts, before we recreate them with software. This is exactly the type of work that I expect engineers to spend more and more time on, in the age of AI, as opposed to pure coding.
We need humans to map the nuances of business and product into structured concepts and relationships, only later to be turned into code by AI. When you do a good job on the former, you will find that the latter becomes trivial, and it feels just right to delegate it to a machine.
Conversely, when we feel that coding is hard, it is often because we try to do the two things together: we try to figure out concepts while we are coding, and that’s where no amount of AI will save us.
To learn more about DDD you can check out:
📘 Domain-Driven Design — the original blue book by Eric Evans (2003) that introduced DDD. This is a deep, theoretical exploration. Perfect for strong foundations.
📕 Implementing Domain-Driven Design — by Vaughn Vernon (2016). this is more of a practical guide to applying DDD in real-world projects. Recommended and easier to digest than Evan’s book.
4) 🗿 Monorepos
This is another controversial one: I believe that today, in 2025, monorepos are the best way to organize codebases. More specifically, I believe they a lot better (not just a little) than polyrepos, for the vast majority of orgs.
The TL;DR is that 1) there have been historically very real pros and cons about monorepos vs polyrepos, but while today the cons of monorepos have been largely solved with tooling, the cons of polyrepos are all still out and about.