Beer & Servers Don't Mix

The T-Shaped Trap: Why Your Org Says It Wants Versatile Engineers but Punishes Them for It

Or: Stop Hiring Full-Stack Engineers and Start Building Full-Stack Teams

It was 2:47 on a Wednesday when Somchai’s cursor stopped moving. The sprint board behind him told the story — three backend cards in “Done,” two frontend cards stuck in “In Progress,” and a deploy date that hadn’t changed in a week. The aircon hummed on the 22nd floor, barely masking the silence of a standup where everyone knew the problem but nobody wanted to say it. He’d finished his work. The team hadn’t finished theirs. So he pulled the next backend card off the backlog and got back to what he was good at.

That moment — the one where a talented engineer chooses personal productivity over team delivery — is the exact point where most organisations break. Not because anyone did anything wrong, but because the entire system told Somchai that was the right thing to do.

There’s a proverb that’s been butchered so thoroughly it should file for defamation: “A jack of all trades is a master of none.” People love quoting it as a warning against breadth. Here’s the full version: “A jack of all trades is a master of none, but oftentimes better than a master of one.” The meaning is literally the opposite of how it’s used. And that mangled interpretation is running your engineering organisation right now.

We say we want T-shaped people. It’s in our competency frameworks, our job postings, our annual review templates. But everything we actually do — how we hire, how we promote, how we plan sprints, and how we structure teams — actively prevents engineers from becoming T-shaped. We’ve built organisations that worship specialisation while paying lip service to versatility, and then we act surprised when our teams can’t deliver end-to-end.

As the management theorist Russell Ackoff once observed, “Managers are not confronted with problems that are independent of each other, but with dynamic situations that consist of complex systems of changing problems that interact with each other.” He was talking about organisational design, but he might as well have been describing a sprint where your backend is three stories ahead and your frontend is drowning — because you’ve optimised for individual throughput instead of team outcomes.

The Unicorn and the Horse

Let’s make a distinction that will save you a lot of grief.

The full-stack engineer is a myth. There’s no such thing as one person who’s genuinely deep across frontend, backend, infrastructure, security, databases, and everything in between. Actually, that’s not entirely true — I’ve met maybe two in my career. But they’re few and far between, and they’re not on any of your teams. Stop writing job descriptions for this person. They’re not coming.

What is not a myth is a full-stack team. Every engineer has their passion — their depth, their vertical bar of the T. Maybe you love frontend and can build accessible React components in your sleep. Maybe you’re the security person who reads CVE reports for fun over your morning coffee. Or maybe you’re one of those bat-shit crazy people who genuinely loves writing APIs in Scala.

That’s the depth, and you need it. Deep expertise is what separates professional engineering from expensive tinkering. But here’s the test — the only test that matters for whether you have a full-stack team:

Say you’re that crazy Scala backend engineer, and the current story’s backend work is done. The frontend isn’t. You have two options:

Option A: Start the backend work for the next story. Stay in your lane. Feel productive.

Option B: Ask what else is left, and how you can help. You know you’ll go slower — because it’s CSS, and you hate CSS, we all do — but you’ll learn. And more importantly, you’ll focus the team on finishing their goal instead of starting something new.

Option A looks like productivity. It is, in fact, the enemy of it. You’ve just increased your work in progress, fragmented the team’s focus, and guaranteed that the current story will take longer to reach “Done” while starting something else that will also take longer to reach “Done.” It’s the classic local optimisation trap — one person’s throughput goes up while the team’s throughput goes down.

Option B is what full-stack actually means. It’s not knowing the whole stack in depth. It’s the lack of fear of working on things you’re unfamiliar with to help the team finish. It’s not a skill set. It’s a mindset.

What Actually Stops People

Let’s be honest about why Option B is rare: it’s not laziness. It’s fear.

Fear of looking incompetent. Fear of slowing down. Fear of opening a pull request and having someone point out that your CSS is garbage, or that you’ve used the wrong React hook, or that your SQL query scans every table in the database. Fear of being judged for being bad at something when your entire career has been built on being good at something.

The basketball coach Phil Jackson — who won eleven NBA championships — put it this way: “The strength of the team is each individual member. The strength of each member is the team.” He wasn’t being motivational. He was describing a structural reality. A team of individually brilliant specialists who won’t cross boundaries isn’t a team — it’s a collection of soloists who happen to share a standup.

This is where psychological safety isn’t just a nice HR concept — it’s a delivery mechanism. Teams where engineers choose Option B are teams where it’s safe to be bad at something while you learn. Where a backend engineer can write mediocre CSS without it becoming a performance review talking point. Where the learning itself is valued, not just the output.

And here’s the thing about that mediocre CSS: it ships. It works. It might not be beautiful, but combined with a code review from someone who knows frontend, it’s good enough. And good enough that ships is infinitely better than perfect that’s still waiting for the specialist who’s three stories ahead in the backlog.

The Accidental Anti-Pattern

If your organisation says it values T-shaped engineers but doesn’t produce them, you don’t have a people problem. You have a systems problem. Look at the machinery:

Hiring filters for specialists. Your job requisitions list one stack. Your interviews test one stack. You’re literally screening out the mindset you claim to want before anyone walks through the door.

Recognition rewards the wrong things. “She’s our best React engineer” gets someone promoted. “He helps everywhere and the team always delivers” gets a pat on the back and a lateral move. I’ve written before about how recognition is a safety signal — what you recognise publicly tells your team what you actually value, regardless of what your competency framework says. If you only celebrate deep technical expertise and never celebrate the engineer who stepped outside their comfort zone to help the team finish, you’re broadcasting a message: stay in your lane. Your engineers aren’t blind — they see what gets recognised and optimise accordingly.

Sprint planning assigns by specialty. You look at the board, you see a frontend task, you assign it to a frontend person. Makes sense, right? Except you’ve just guaranteed that nobody ever needs to stretch. You’ve turned your sprint planning into a sorting algorithm that reinforces silos every two weeks.

Code review as gatekeeping. “That’s not how we do it in the backend” is technically helpful feedback. It’s also a social signal that says you don’t belong here. When crossing a boundary means walking into someone else’s territory and having your work picked apart by experts, most people will stop crossing.

None of this is malicious. It’s all perfectly rational individual behaviour that produces a collectively terrible outcome. Your specialists become bottlenecks not because they’re bad engineers, but because your system has made them the only people who can do certain types of work — and then given them no reason to change that.

“How Would You Like to Learn Something New?”

Years ago, in the early days of Agoda building out some of our infrastructure, my team was tasked with contributing heavily to a new backend API. So they gave me two engineers from the backend team that owned it — yes, we had backend teams a decade ago; we weren’t always as mature as we are now.

The first two sprints told an interesting story. Most of the immediate work was on the frontend, building on top of the existing APIs. My two backend engineers were sitting there with nothing to do in their speciality. So I walked over and the first words out of my mouth were, “How would you guys like to learn something new?”

Not “You need to do frontend work.” Not “We need you to pick up these React tickets.” There’s something subtle in that framing that matters more than it might seem. By asking them to learn, I’d removed the pressure to perform. That pressure — the expectation that you should be immediately productive in an unfamiliar domain — is the single biggest blocker in most engineers’ heads when it comes to working outside their expertise.

To ease them in, I started talking about the functional patterns the search team had started using with React, and how similar they were to patterns in Scala that these guys already knew and loved. Suddenly it wasn’t a foreign territory — it was a different dialect of a language they already spoke.

Weeks later, their manager came to find me. He pulled me into a meeting room — the vinyl flooring squeaking under his chair as he sat down — and said, “I’ve heard those two backend engineers are working on frontend.” The tone made it clear this was not intended as a compliment.

I ignored the sentiment entirely. “Yeah, and they’re learning a lot, and the team is going well.”

He was visibly taken aback. He’d come prepared for a different conversation. He had to regroup before his next sentence: “We had a commitment that they would help build out the new backend.”

“We have a commitment to deliver the new extranet,” I replied. “We solve problems. We don’t build systems.”

The conversation was short. We continued.

But here’s the best part — those two backend engineers didn’t just learn React. They started having conversations with the frontend team, teaching them functional patterns that could improve their client-side code. The knowledge transfer went both ways. The backend engineers gained frontend skills. The frontend engineers gained deeper functional programming understanding. Both teams got better.

That’s not a fairy tale. That’s what happens when you remove the fear and replace it with curiosity. But it doesn’t happen on its own — you need the support of leadership and the organisation behind you. Which is exactly what I gave them. The space to learn, the cover to be slow, and the message that finishing the team’s goal mattered more than staying in their lane.

The Generalist Trap

Now, before this turns into a manifesto against specialisation, let me be clear: breadth without depth is just tourism.

The engineer whose CV says “full-stack” but who writes React that isn’t accessible, SQL that scans every table, and deployment pipelines that work… eventually — that person isn’t T-shaped. They’re a flat line. They can do a bit of everything and none of it well. Every codebase they touch gets a thin layer of “good enough” that compounds into a thick layer of technical debt.

The horizontal bar of the T isn’t about knowing everything. It’s about willingness — the willingness to step outside your depth, to be uncomfortable, to learn enough to be useful even if you’ll never be an expert. The vertical bar is what makes the horizontal bar valuable. Without deep expertise somewhere, you’re just spreading mediocrity efficiently.

As the educator and philosopher John Dewey noted, “We do not learn from experience. We learn from reflecting on experience.” An engineer who dabbles in everything but reflects on nothing doesn’t become T-shaped — they become dangerously shallow. The T comes from going deep enough in one area to develop genuine engineering judgment, and then applying that judgment when you venture into unfamiliar territory.

Interviewing for the Mindset

You can’t test for T-shaped skills in an interview — the whole point is that the horizontal bar is always growing. But you can absolutely test for the willingness.

Ask candidates about a time they worked on something outside their expertise. Listen carefully. The specialist will tell you about a time they had to do something unfamiliar and how quickly they got back to their comfort zone. The T-shaped engineer will tell you about what they learned, how it changed their perspective, and — crucially — how it made them better at their primary skill.

Ask questions that probe the edges of their expertise — but don’t be blunt about it. If they’re a backend engineer, try something like, “Do you get a chance to work on the React code much?” or “What’s your take on state management — Redux or something lighter?” Watch their face, not just their answer. The engineer who lights up and says “yeah, I’ve been getting into it” is telling you something very different from the one whose expression tightens before they say “Sure, sometimes, but not much.” You’re not testing React knowledge. You’re testing whether the boundary between “my work” and “the team’s work” feels like a wall or a door.

Ask them what they’ve been learning recently. It’s a simple question, but the answer is revealing. The engineer who’s been tinkering with something outside their comfort zone — the backend person who’s been playing with CSS Grid, the frontend engineer who’s been reading about distributed systems — that’s someone whose T is actively growing. The one who can only talk about going deeper into what they already know isn’t wrong, but they’re telling you where their ceiling is.

Building the Full-Stack Team

If you’re an engineering leader reading this and recognising your own organisation in the anti-patterns above, the path forward isn’t complicated. It’s just uncomfortable — which, fittingly, is exactly the point.

Plan sprints around stories, not specialties. When you assign work, assign whole stories to pairs or small groups, not individual tasks by skill. Let the team figure out who does what within the story. You’ll be surprised how often people volunteer for the unfamiliar when the team context makes it natural instead of forced.

Reframe code review. Reviews across speciality boundaries should be teaching moments, not gatekeeping exercises. When a backend engineer submits frontend code, the review should focus on “here’s how to make this better” not “this isn’t how we do it.” The tone difference is everything.

Reward team outcomes, not individual output. If your promotion criteria don’t include “helps the team deliver,” add them. If they do include them but nobody actually gets promoted for it, you have a values gap that your engineers have already noticed.

Create psychological safety around learning. This doesn’t mean lowering standards. It means explicitly acknowledging that someone working outside their expertise will be slower and less polished — and that this is not only acceptable but actively valuable. The short-term cost of a backend engineer writing slightly worse CSS is vastly outweighed by the long-term benefit of a team that can flex to wherever the work is.

Protect the depth. None of this means everyone should do everything all the time. Your Scala expert should still spend most of their time writing Scala. Your React specialist should still lead frontend architecture decisions. The T needs a strong vertical bar. But when the sprint needs someone to pick up a frontend card to get the story across the line, “that’s not my area” shouldn’t be an acceptable answer.

The Bottom Line

The basketball player and cultural icon Kobe Bryant once said, “I’ll do whatever it takes to win games, whether it’s sitting on the bench waving a towel, handing a cup of water to a teammate, or hitting the game-winning shot.” That’s the mindset. Not “I’ll do whatever it takes as long as it’s in my job description.” Not “I’ll help out once I’ve finished my own backlog.” Whatever the team needs.

The full-stack engineer is a myth worth retiring. The full-stack team is a reality worth building. The difference isn’t in what your engineers know — it’s in what they’re willing to do. And that willingness isn’t a character trait you either have or you don’t. It’s a product of the system you’ve built around them.

If your engineers won’t cross boundaries, look at what happens when they try. Look at your hiring filters, your promotion criteria, your sprint planning rituals, your code review culture. Somewhere in that machinery is a message — loud and clear — that says stay in your lane.

Change the message, and you change the team.

Now, if you’ll excuse me, I need to go review a pull request from our backend engineer. It’s a React component. The CSS is questionable. The logic is solid. And it’s exactly what the team needed to ship today.