How a small team of senior engineers ships like a large one
All 7 engineers on our team are senior. These four habits let us ship at the pace of a large team.
A small team must keep its work simple and clear. A large team must add process to get the same discipline.
Senior by default
Every engineer on our team shipped production systems and was on call for them. Nobody on the team needs each step written out. The engineer who designs a system also builds it and owns it.
We have fewer handoffs, and fewer specs for someone to misread later. The people who make a decision also live with its results.
Design the boundaries first
At the start of a project, we draw the boundaries. We decide what the parts are, where they join and what the data can do. This takes time in the first week. It saves time in every week after that.
type Cents = number & { readonly __brand: "Cents"} function toCents(dollars: number): Cents { return Math.round(dollars * 100) as Cents} const price = toCents(4.99)const fee: Cents = 499money.ts(10,7): error TS2322: Type 'number' is not assignable to type 'Cents'. Type 'number' is not assignable to type '{ readonly __brand: "Cents"; }'.
The compiler accepts the price, because toCents returns Cents. In the last line, it rejects a plain number where the code expects Cents. Two more examples are a module that cannot reach into the internals of another module, and a state machine that cannot enter an illegal state. We make each of these decisions once, at the boundary. Each one prevents a full class of bugs for the life of the project.
Write for the second engineer
Most engineers can make a first version work while the problem is fresh in their head. Later, a second engineer arrives without that context. That engineer must change one part and keep the other parts intact.
We write for that engineer. We give each thing a name that makes sense out of context. We write tests that state the intent of the code. We add a comment where the code does not show why it exists. These habits keep the team fast for the life of the project.
Ship early, then improve
We put software that works in front of real users early. We watch how they use it. Then we improve the parts that matter to them and leave the rest.
We use these four habits on every project.