🎯 Chapter Insight
Software development is often described as an individual craft.
We picture a developer sitting in front of a screen, solving problems, writing code, and gradually building a system.
In reality, most meaningful software is created by teams.
Even when one person writes a particular piece of code, that code usually depends on decisions, knowledge, constraints, and ideas contributed by many others.
Working together is therefore not simply about splitting a project into tasks and assigning each one to a different person.
True collaboration means sharing the thinking behind the work.
It means discussing the problem before the solution is fixed, exposing assumptions while they can still be challenged, and learning from other perspectives while the code is being shaped.
Pragmatic developers understand that collaboration can improve more than productivity.
It improves decisions.
💡 Developer Lens
In everyday engineering, collaboration can take many forms.
Pair programming allows two developers to work through a problem together in real time.
Mob programming expands that idea to a larger group.
Code reviews expose an implementation to perspectives beyond the original author.
Design discussions allow assumptions to be questioned before they become architecture.
Debugging sessions bring together different mental models of how the system behaves.
Each of these practices creates opportunities for something important to happen:
Someone else sees what you missed.
A developer may notice an edge case you had not considered.
Another may recognise that a complicated implementation can be replaced with something simpler.
Someone unfamiliar with the code may ask a basic question that reveals the design is harder to understand than you thought.
These moments are valuable because software problems rarely have only one reasonable solution.
Another perspective expands the solution space.
Share the Thinking, Not Just the Result
Teams often collaborate only after the main thinking is finished.
A developer works independently for hours or days, creates a solution, and then opens a pull request.
At that point, collaboration begins.
But much of the most important work has already happened.
The assumptions have been made.
The architecture has been chosen.
The trade-offs have been accepted.
The code reviewer is now reacting to a completed solution rather than participating in the reasoning that created it.
This can still produce useful feedback, but the cost of changing direction is much higher.
Working together earlier changes the dynamic.
Instead of asking:
“Is this implementation acceptable?”
the team can ask:
“What is the best way to approach this problem?”
That is a much more powerful conversation.
Collaboration is often most valuable before the solution becomes expensive to change.
Collaboration Challenges Assumptions
Every developer approaches a problem with assumptions.
Some come from experience.
Some come from familiarity with the codebase.
Some come from previous projects.
And some are simply invisible until another person questions them.
Imagine you are designing an API and automatically assume that a certain operation must be synchronous.
Another developer asks:
“Why does the caller need the result immediately?”
Suddenly an asynchronous approach becomes possible.
Or perhaps you are debugging a problem and assume the database is returning incorrect data.
A colleague asks whether the request may actually be executed twice.
The investigation moves in an entirely different direction.
This is one of the strongest benefits of collaboration.
Other people interrupt our mental shortcuts.
They force assumptions into the open where they can be examined.
Pairing Is About More Than Two Keyboards
Pair programming is sometimes misunderstood as two developers doing work that one developer could have completed alone.
If productivity is measured only in lines of code written per hour, that criticism may appear reasonable.
But development is not typing.
The difficult part is usually reasoning.
What should we build?
What assumptions are we making?
What are the edge cases?
How should responsibilities be divided?
What will make this difficult to change later?
Pairing brings two minds into that reasoning process.
One person may focus on the immediate implementation while the other notices the larger structure.
Roles shift continuously.
Questions get answered immediately instead of becoming comments in a pull request hours later.
Knowledge transfers naturally while solving the real problem.
The value is not simply two people producing code.
It is two people continuously validating the thinking behind the code.
Code Reviews Are Knowledge Sharing
Code reviews are often framed primarily as quality control.
Find bugs.
Enforce conventions.
Prevent bad code from reaching production.
Those are useful outcomes, but reviews can provide much more.
A good code review spreads knowledge.
The reviewer learns how another part of the system works.
The author learns alternative approaches.
Architectural decisions become visible to more people.
Patterns become shared across the team.
Questions reveal where code is difficult to understand.
A review should therefore not feel like one developer judging another developer’s work.
It should be a conversation about improving the solution.
The most useful review comment is not always:
“This is wrong.”
It may be:
“What led you to this approach?”
That question can uncover context the reviewer did not have, or reveal an assumption the author had not considered.
Either outcome improves shared understanding.
Collaboration Reduces Knowledge Silos
One of the biggest risks in a software team is knowledge becoming concentrated in a few individuals.
There is the person who understands the authentication system.
The developer who knows the deployment pipeline.
The engineer who is the only one willing to touch the billing code.
The colleague everyone calls when a particular integration fails.
This may feel efficient in the short term.
Experts solve familiar problems quickly.
But it creates fragility.
When that person is unavailable, work slows down.
When they leave the team, knowledge leaves with them.
When decisions are discussed only with that person, others never develop the same understanding.
Collaboration spreads knowledge through everyday work.
Pairing allows expertise to transfer naturally.
Joint debugging exposes system behaviour to more developers.
Design discussions distribute context.
Code reviews make changes visible beyond their author.
The goal is not for every developer to know everything.
That is unrealistic.
The goal is to avoid creating areas of the system that only one person can safely understand.
Explain Your Thinking
Collaboration also forces us to articulate ideas.
That alone can improve them.
A solution may feel perfectly clear inside your head.
Then you try to explain it to another developer.
Halfway through the explanation, you realise the logic is difficult to justify.
Perhaps the design contains too many exceptions.
Perhaps the abstraction is not as clean as it seemed.
Perhaps you cannot clearly explain why one component owns a particular responsibility.
Explaining your reasoning is a form of testing.
If an idea is difficult to communicate, it may be difficult to maintain as well.
Another developer does not even have to provide the answer.
Sometimes the act of explaining the problem reveals it.
Collaboration Needs Psychological Safety
Working together only helps when people feel able to speak.
If developers are afraid to ask simple questions, challenge senior colleagues, or admit that they do not understand something, collaboration becomes superficial.
Meetings happen.
Reviews happen.
But important assumptions remain unchallenged.
Healthy engineering teams make room for uncertainty.
“I do not understand why we need this.”
“Could you explain this assumption?”
“I think there may be a simpler approach.”
“I might be missing something, but what happens if…?”
These questions should be valuable contributions, not signs of weakness.
Software is complex enough that nobody sees everything.
A team that can challenge ideas without attacking people has a significant advantage.
The objective is not to prove who has the best answer.
It is to arrive at the best solution the team can find together.
Collaboration Does Not Mean Consensus on Everything
Working together does not mean every decision requires a meeting.
Too much collaboration can create its own problems.
If every variable name requires group agreement, progress stops.
Teams still need autonomy.
Developers should be trusted to make local decisions independently. The skill is recognising when the value of another perspective outweighs the coordination cost.
Complex design decision?
Collaborate early.
Unfamiliar subsystem?
Pair with someone who knows it.
Difficult production issue?
Investigate together.
Small isolated implementation detail?
Probably just solve it.
Pragmatic collaboration is intentional.
The goal is not maximum interaction.
It is using interaction where it improves understanding, reduces risk, or spreads useful knowledge.
Different Perspectives Improve Solutions
Teams are valuable partly because developers think differently.
One person may focus naturally on architecture.
Another may notice performance implications.
Someone else may think about usability.
Another may immediately identify security risks.
A developer familiar with the domain may spot a business rule others missed.
A newcomer may question conventions that experienced team members stopped noticing years ago.
These perspectives are not obstacles to alignment.
They are resources.
If everyone approaches a problem in exactly the same way, collaboration adds little.
The value comes from bringing different mental models together and allowing them to challenge one another.
Better software often emerges from that friction.
🧭 Reflection
Think about how you solve problems in your current team.
How often do you involve another developer while the solution is still being shaped?
Do discussions happen before implementation or mostly during code review?
Are difficult areas of the system understood by several people, or concentrated in the heads of a few individuals?
When you are stuck, do you spend hours pushing forward alone before asking for another perspective?
And when another developer asks a question about your solution, do you treat it as resistance or as an opportunity to test your reasoning?
Working together is not just about getting more work done.
It is about improving the thinking behind the work.
⚙️ Practical Tip
Choose one non-trivial task this week and deliberately solve part of it with another developer.
Do not wait until the implementation is complete.
You could:
- Pair on the initial implementation
- Investigate a difficult bug together
- Walk through the design before writing code
- Ask another developer to challenge your assumptions
- Explore two possible approaches together
- Review an unfamiliar area of the system as a pair
While doing it, pay attention to what changes in your thinking.
Did the other person ask something you had not considered?
Did explaining the problem expose a hidden assumption?
Did you learn something about another part of the system?
Did the solution become simpler?
The goal is not simply to compare answers afterward.
Share the reasoning that creates them.
That is where collaboration becomes more than teamwork.
It becomes part of how better software is built.
🔢 #47 of 53 | The Pragmatic Programmer Series
This post is part of my 53-week series summarizing The Pragmatic Programmer, one timeless principle each week, translated into modern software practice and reflection.








