Skip to content
Career

Why soft skills matter more than you think as a developer

Good code gets you through the door. Speaking up early, writing for your reader and asking why are what make a developer worth trusting, and agents haven't changed that.

Daniel HallSolutions Architect
14 min read

A developer picks up a ticket estimated at three hours. Forty-five minutes in, something looks off: an unexpected dependency, or a rabbit hole opening up under the original plan. If they raise it then, the team can tweak the approach, split the work, or check with the client whether the effort is still justified. If they keep quiet and raise the alarm two and a half hours in, most of those options have gone.

I’ve watched some version of that play out more times than I can count, and it’s rarely a technical failure. Throughout my career I’ve worked with many technically brilliant developers, people who are deeply skilled and genuinely committed to their craft. But the ones who truly stand out are also confident communicators, able to adapt to what a project or a client actually needs.

This is something I care a great deal about. Time and again, I’ve seen strong soft skills multiply a developer’s impact, especially in fast-moving, team-based environments.

Info

Updated October 2026: tidied up, and added a section on where AI fits in now.

Communication

“Communication is key.” It’s a cliché for a reason. In software development, and in most careers, strong communication makes everything else smoother. You can be technically brilliant, but if you struggle to communicate clearly, it’s going to limit how well you collaborate and how well your work fits into the bigger picture.

Escalating effectively when things aren’t going to plan

It’s the situation from the top of this post, and I’ve seen it countless times. A developer picks up a ticket, the team agrees on an estimate, and work begins. Then something goes wrong, and instead of raising it, the developer keeps going, hoping to solve it within the original estimate. Time runs out, the ticket overruns significantly, and no one’s had the chance to course-correct.

This can quietly derail a sprint, or force the business to cap the time spent because the return on investment just doesn’t stack up.

The key skill here is to notice early. Start with a rough plan. As you get into the detail, flag any concerns or blockers as soon as they appear. If you feel yourself sliding into a deeper technical challenge than expected, pause and raise it. Escalating doesn’t mean failure. It gives your team the chance to respond while there’s still time to adjust, and that window is what keeps a project on track.

Adapting to your audience

As a developer, you’ll often need to explain your approach to a feature, or your resolution to a bug, to someone who isn’t technical, or who is but doesn’t know the project in the same depth as you. Whether it’s a support manager, a client or a fellow developer, it’s important to communicate in a way that matches your audience.

It might sound obvious, but I’ve worked with many developers who overlook this entirely.

When writing an update on a ticket, I like to break it into two clear parts:

  • A concise overview of what’s been reviewed, and what has (or hasn’t) changed.
  • A list of next steps. These might include questions for the client, or simply note that the change will be included in the next release.

Whether it’s an update, an email or documentation, step into the role of the person you’re writing for. Ask yourself:

  • What do they actually need to know?
  • What are they going to do with this information?
  • What might be obvious to me, but not to them?

Over-explaining might feel unnecessary at times, but I’d argue it’s far better to anticipate gaps in understanding than to create confusion or force a teammate to rephrase your update for someone else.

Considering the wider picture

It’s one thing to fix a bug, it’s another to fully solve the problem.

Let’s say you’ve fixed an issue where addresses weren’t syncing from a microservice into your order fulfilment platform. Great. But in the meantime, several orders on a live e-commerce site have failed silently, or are now stuck in limbo. Your fix is ready to deploy, but what happens next? What about the data that’s already been affected?

This is where stepping back and considering the wider picture becomes essential. As a developer, it’s easy to see your role as delivering working code. But the real value comes from anticipating the knock-on effects of a bug and helping to resolve them too.

In cases like this, ask yourself:

  • Do the affected records need manual intervention?
  • Could a script be written to patch the bad data?
  • Does the client need to contact impacted customers, and have we made it easy for them to know who those are?

Sometimes it’s not your job to carry out all of that work, but it is your responsibility to raise it. Offer options and flag the likely consequences, so it’s clear you’ve thought about restoring normal service as well as fixing the bug.

Handling and giving feedback

Feedback is part of everyday life as a developer, whether you’re reviewing someone else’s pull request or responding to comments on your own. And while most teams have a process for it, not everyone has the mindset.

Receiving feedback well means separating your code from your ego. I’ll put my hands up: I struggle with this constantly. It’s natural to feel a bit defensive when something you’ve written is questioned, especially if you’ve spent hours on it. But those comments usually aren’t personal. They’re about catching edge cases or keeping to team standards, and taking them in the spirit they’re intended makes collaboration smoother.

Giving feedback is equally important, and arguably trickier. It’s easy to spot issues, but offering helpful, respectful feedback takes a bit more effort. Instead of just pointing out what’s wrong, explain why and, where possible, suggest alternatives. It’s not about policing other people’s code; it’s about helping each other write better code.

A good rule of thumb: review code the way you’d want yours to be reviewed. Avoid nitpicking unless it genuinely matters, and remember there’s a person on the other side of the comment. Google’s code review guidelines are worth a read on this, and Conventional Comments is a simple way to make clear whether a comment is a blocker or just a suggestion.

Documentation

Using the right tone for the right context

When it comes to professional documentation, things like technical specifications, integration plans, or anything that’s going to be reviewed and signed off by clients or stakeholders, tone plays a bigger role than many developers realise.

In these kinds of documents, I avoid personal or conversational phrasing like “I think we should…”, “you’ll need to…” or “we will do…”. It might sound natural, but it can come across as too casual or imprecise in a professional setting. Instead, I aim for a more neutral, objective tone: “It is recommended that…”, “The client should…” or “This approach ensures that…”. It removes ambiguity about who is responsible, and it reads as considered rather than casual.

This isn’t about sounding robotic or overly formal, it’s about writing in a way that reflects the purpose of the document. A technical specification, for example, isn’t a Slack message or a dev note. It might be passed between departments, signed off at board level, or used months later to resolve a dispute. The tone you use gives weight to the content and shows you’ve written it with the appropriate level of care.

Think of it this way: the tone you choose should match how permanent the document is and who’s going to read it.

Your company probably has its own guidance on how documents should be written, and you should follow it. What I’m describing is the habit underneath, which travels with you between companies.

Writing for clarity and future readers

Documentation isn’t just for the person reviewing your pull request today. It’s for the developer picking up the project in six months, the new starter trying to understand your logic, or even future you, wondering what on earth past-you was thinking.

When writing anything that someone else might need to follow, whether it’s a README, a Confluence page or inline code comments, it’s worth pausing to think: Would this make sense to someone without the same context I have right now? Clear writing can save hours of back-and-forth. For anything bigger than a README, Diátaxis is a handy way to keep tutorials and reference material from bleeding into each other.

That doesn’t mean every document needs to be exhaustive. It means being intentional: explain decisions, define acronyms, and assume the reader might not have been in the meeting where the requirement was discussed. If something is nuanced or based on a trade-off, note it (architecture decision records exist for exactly this). The extra lines that explain why something was done that way are often what turn a half-useful document into a genuinely valuable one.

Scoping and understanding requirements

Digging into the why behind a feature or change

It’s easy to take a ticket at face value, especially when you’re mid-sprint and trying to move quickly. But if you don’t take the time to understand the why behind a feature or change, you risk building something that’s technically correct but functionally off the mark.

Understanding the reason behind a request strengthens your ability to plan effectively. It shapes how you break down the work and how you anticipate edge cases or dependencies. You’re not just writing code, you’re making decisions that affect how future work builds on top of it.

It also helps you challenge the brief, when appropriate. A client might ask for one thing, but when you dig into why they want it, you sometimes discover they actually need something slightly different, or far simpler. That kind of clarity can save a lot of wasted build time.

Asking why doesn’t mean being difficult. It shows that you care about solving the right problem, and it positions you as a collaborator in the process, not just a pair of hands.

Challenging and clarifying scope diplomatically

It’s not uncommon to receive a ticket or request that’s vague, overambitious, or just doesn’t make sense once you start looking at it more closely. In those moments, the ability to challenge and clarify the scope, without sounding obstructive, is a key skill.

The goal isn’t to block progress or push back for the sake of it. It’s to make sure what’s being asked is achievable and clearly understood before time and effort go into building the wrong thing. Sometimes that means asking for missing details. Other times, it means gently questioning whether the request is solving the right problem at all.

The way you raise those points matters. Avoid defensive or loaded language. Instead of “this won’t work”, try “can I check the intent behind this?” or “would you be open to an alternative approach?” Framing questions in a constructive way invites conversation and keeps everyone aligned around the outcome.

You’re not being awkward; you’re protecting the quality of the work and the budget. And if you do it with care, most clients and project managers will respect you more for it.

Stakeholder awareness and empathy

Understanding other perspectives

As developers, it’s easy to view a project through the lens of code quality, architecture or technical debt. Those things matter, but they’re just one part of the wider picture. Clients, project managers, designers and QA testers all bring their own priorities and pressures to a project.

Understanding those perspectives helps you work more effectively as part of a wider team. A client might be under pressure to hit a campaign deadline. A QA tester might be juggling multiple release streams. A PM might be trying to balance scope creep with stakeholder expectations. If you understand where someone’s coming from, your responses and decisions become more considered, and often more helpful.

That doesn’t mean compromising on good engineering practice. It means communicating in a way that recognises what matters to others. Sometimes that’s as simple as adjusting your language. Sometimes it’s knowing when to explain a trade-off, or when to just get something over the line because time is tight.

Empathy in a development context is less about being soft and more about being aware of what everyone else is dealing with. Over time, that awareness is a big part of what makes people trust your judgement.

Adjusting approach based on context

Not every technical hill is worth dying on.

Part of growing as a developer is learning when to push for the right approach, and when to take a more pragmatic path. That doesn’t mean compromising your standards; it means recognising that context matters. Deadlines, budgets, competing priorities and the level of risk all play a part in shaping what “good” looks like in a given moment.

There are times when it’s absolutely right to speak up: when a shortcut introduces technical debt that will be hard to reverse, or when a rushed fix could hurt the user experience or data integrity. But there are also times when the best course is to flag your concerns, document the decision, and move forward, because the project needs momentum more than perfection.

This kind of judgement comes with experience, but it also requires awareness. Read the room, and know what the project’s priorities are. Being able to adapt your approach to the situation is what makes you dependable, not just technically, but as a teammate.

Time and self-management

Prioritising realistically

There’s a point in every developer’s career where they realise that perfect isn’t always the goal. Done and deployed often has more value.

Knowing where to invest your time, and where to be pragmatic, is a skill that develops over time. Some tickets need careful architectural planning and future-proofing. Others just need to be solved cleanly and quickly, because the impact is low or the context is temporary. Understanding the difference (and not over-engineering where it’s not needed) is part of being effective.

This doesn’t mean cutting corners. It means working in a way that’s proportionate to the task and the value it delivers. If you find yourself endlessly polishing or refactoring something that’s already functional and stable, it might be time to step back and ask: is this still helping the project, or is it just satisfying me?

Prioritising realistically also means communicating. If time is tight, surface the constraints and work with your team to find a sensible balance. That awareness builds trust and makes you someone others can rely on when deadlines start to matter.

Taking ownership

Taking ownership doesn’t mean doing everything yourself. It means making sure a piece of work is followed through properly, even if that means handing it over with clear notes, or raising an issue when you can’t progress.

Ownership is about responsibility. If a bug is discovered in a ticket you worked on, don’t shrug it off as someone else’s problem. Look into it and help figure out what went wrong. Similarly, if you’re stuck or blocked, don’t just leave it sitting there. Escalate it with the right context so others can step in and help move things forward.

A developer who takes ownership is someone others can trust. Not because they never make mistakes, but because they handle them well and see things through.

It’s easy to focus just on your current task list, but keeping an eye on the outcome of your work, and how it affects others, is what marks you out as someone who cares about the bigger picture.

Where AI fits in

An agent drafts most of my code now. Day to day that’s Claude Code, and I’ve written separately about what that shift means for the architect’s job. I’m far from unusual: in the 2026 Stack Overflow Developer Survey, 73% of respondents said they use coding assistants and agents daily.

You might expect that to make everything above matter less. In my experience it’s the other way round. An agent won’t usually stop at 45 minutes and tell the team the estimate was wrong; left to itself, it keeps going until it has something that works. Nor will it ask the client why they want a feature, or notice that the fix has left a pile of stuck orders behind it. Those are still my jobs, and with less of my day spent typing code, they make up a bigger share of it.

Documentation has gained a second reader, too. The README, the ticket and the decision record I write for the next developer are now also context for the agent, and an agent takes a vague ticket just as literally as a rushed new starter would, only faster.

The 2025 DORA report describes AI’s primary role as “an amplifier, magnifying an organization’s existing strengths and weaknesses”. In practice, teams that already communicate well get quicker with agents, and teams that don’t tend to see their misunderstandings reach production sooner.

Final thoughts

Technical skills might get you through the door as a developer, but it’s soft skills that determine how far you go.

None of them come quickly, and no one gets them right all the time. They’re the skills I’ve seen make the biggest difference over the years, and they’re the ones I still actively work on myself, starting with speaking up at 45 minutes rather than two and a half hours.

Further reading

Related posts