Chapter 2: You Are Not Your Stack

“Letting go gives us freedom, and freedom is the only condition for happiness.”
— Thich Nhat Hanh

I spent three years convincing myself I was a Java developer.

Not someone who wrote Java. A Java developer. The distinction mattered to me, though I couldn’t have told you why. I had opinions about dependency injection frameworks. I had a favorite IDE theme. I had engaged in lengthy comment wars about checked exceptions. When someone asked what I did, I didn’t say “I write software.” I said “I’m a Java guy.”

Then the company decided to rewrite everything in Go.

The announcement came on a Thursday afternoon. By Friday, I was angry. By Monday, I was bargaining. I made arguments about ecosystem maturity and hiring pipelines and the sunk cost of our existing codebase. Some of these arguments were even reasonable. But underneath them was something less rational: the feeling that if we stopped writing Java, I would somehow become less myself.

That feeling is worth examining. Because it turns out I had confused familiarity with identity. And that confusion cost me about six months of fighting a transition that was going to happen whether I fought it or not.

Here’s what those six months looked like: I became the person who derailed meetings. I’d sit in planning sessions with my arms crossed, waiting for my turn to explain why the timeline was unrealistic, why the Go ecosystem wasn’t ready, why this was a mistake we’d regret. My manager started scheduling architecture discussions without me. I told myself this was because they didn’t want to hear the truth. It was actually because I’d made myself exhausting to be around.

A colleague I respected pulled me aside one afternoon. “You know they’re going to do this anyway,” she said. “The only question is whether you’re going to be part of it or whether you’re going to be the guy who wasn’t.” I didn’t have a good answer. I knew she was right. But knowing didn’t make it easier to let go.

The worst part wasn’t losing the argument. It was realizing, months later, that I’d spent half a year being the problem rather than solving problems. The reputation I’d built as a thoughtful engineer had been replaced by a reputation as someone who couldn’t adapt. That took longer to fix than learning Go ever did.


The Weight of Attachment

Tools accumulate emotional mass the longer you use them. This happens so gradually you don’t notice until something threatens to take them away.

I remember the first time I felt genuinely competent in Java. I was debugging a threading issue, and for the first time, I could see the whole system in my head. I knew where the locks were. I knew what the garbage collector was doing. I knew, without checking, that the problem was in how we were sharing state between handlers. That feeling of mastery was intoxicating. I wanted more of it.

The trouble is, mastery in one context can become a cage. The deeper your expertise, the more you have to lose. The more you have to lose, the harder it becomes to start over somewhere else. And the industry has a way of asking you to start over whether you’re ready or not.

I’ve watched this happen to good engineers more times than I can count. The Angular expert who couldn’t see why React might be worth learning. The Oracle DBA who dismissed PostgreSQL as a toy. The mobile developer who insisted native would always beat cross-platform, right up until their company’s entire iOS team was replaced by three Flutter engineers.

None of these people were stupid. They were attached. And attachment made them brittle in exactly the moment they needed to be flexible.


What Tools Actually Teach

Every tool carries lessons in its design. A framework encodes someone’s opinions about how software should be structured. A language makes certain patterns easy and others awkward. When you use a tool long enough, you absorb those opinions without realizing it. They become part of how you think.

This is valuable. It’s also temporary.

Go taught me things Java never did. The aggressive simplicity, the refusal to add features, the explicit error handling that felt tedious until I realized how much information I’d been losing to swallowed exceptions. I resisted these lessons at first. They felt like constraints rather than wisdom. But the constraints had a point, and eventually I stopped fighting them.

What I didn’t expect was how Go would change how I wrote Java when I went back to it. I started questioning patterns I’d used for years. I noticed ceremony I’d stopped seeing. The tool had taught me something that transcended the tool itself.

This keeps happening if you let it. Each new technology is a lens that reveals things the previous one obscured. But you have to be willing to pick up the lens. You have to be willing to see your old certainties as provisional rather than permanent.

I’ve noticed that the engineers who stay curious tend to treat their tools as teachers rather than as tribes. They learn what the tool has to offer, they carry that learning forward, and they don’t mistake the lesson for the classroom.


Labels and Their Limits

Job titles are convenient fictions. “Backend engineer.” “Frontend developer.” “DevOps specialist.” “Data scientist.” These labels help companies organize headcount and help recruiters filter resumes. They are not descriptions of who you are.

But they can start to feel that way.

I spent years avoiding frontend work because I had decided I was a backend person. When a project required some React, I felt a strange reluctance that had nothing to do with capability. I could learn React. The problem was that learning React felt like an identity violation. Backend engineers don’t do frontend. That’s not who we are.

This is, obviously, ridiculous. And yet the feeling was real. Labels create boundaries, and boundaries become self-fulfilling. The more I avoided frontend work, the more alien it seemed. The more alien it seemed, the more justified I felt in avoiding it. The label I’d chosen had become a wall I was maintaining without realizing I was the one who built it.

There is a specific kind of freedom in using labels when convenient and ignoring them when limiting. In introducing yourself differently depending on context. In moving between domains without apology, picking up what’s useful and carrying it forward. Deep expertise held loosely looks like that: confident but not defensive, specialized but not trapped.

What would your work look like if you stopped policing the boundaries of your job title?


The Core Beneath the Stack

If not your tools, then what defines you as an engineer?

This question used to bother me. If I wasn’t a Java developer, what was I? The tools felt concrete. The alternative felt vague.

But here’s what I’ve noticed: the engineers who navigate change best have something stable underneath the shifting surface. Not a technology, but a set of capabilities that transfer across technologies. The ability to break a problem into smaller problems. The ability to explain a complex system to someone who doesn’t share your context. The ability to read code written by someone whose mind works differently than yours and figure out what they were trying to do.

These skills don’t show up on a resume the way frameworks do. They’re harder to measure, harder to interview for, harder to brag about. But they’re what actually make someone useful across a career that will span dozens of tools and probably several paradigm shifts.

I think of it like this: the tools are the instruments, but you’re the musician. A good musician can pick up a new instrument and make something worth hearing while they learn. A mediocre musician with a great instrument is still mediocre. The instrument matters, but not as much as the hands holding it.

The question isn’t whether you know Kubernetes. The question is whether you can look at a system you’ve never seen before and start asking useful questions. The question is whether you can sit with confusion long enough for understanding to emerge. The question is whether you can teach what you know and learn what you don’t without making either feel like a threat.


Letting Go as Practice

The Go rewrite I resisted so fiercely turned out fine. Better than fine, actually. The new codebase was cleaner than the old one. The deployment story was simpler. Some of the patterns I’d insisted were essential turned out to be incidental, artifacts of a language rather than requirements of the problem.

More importantly, I learned something about myself. I learned that my resistance had very little to do with engineering judgment and quite a lot to do with fear. Fear of incompetence. Fear of starting over. Fear of losing the status that came from being the person who understood the system.

That fear doesn’t go away. Even now, when I hear about a new framework or a new paradigm, there’s a small part of me that hopes it fails. That hopes I won’t have to learn it. That hopes the things I already know will remain sufficient.

I’ve learned to notice that feeling without acting on it. It’s information, not instruction. The fear tells me where my attachments are. It doesn’t tell me what to do about them.

Letting go of your stack isn’t a one-time event. It’s a practice. Each time a tool becomes obsolete, each time a paradigm shifts, you get another opportunity to notice your attachments and choose whether to maintain them. The choice gets easier with repetition, but it never becomes automatic.

Staying relevant across decades isn’t about picking the right technology early. It’s about learning to hold your tools lightly. Finding your identity in something more durable than whatever framework is trending this quarter.


Still Here

Tomorrow, the technology you love might be declared legacy. The skills you’ve honed might become less valuable than skills you haven’t developed yet. The certainty you feel about the right way to build software might turn out to be a local maximum, a reasonable approach for one context that doesn’t generalize.

This isn’t a threat. It’s the nature of the work.

You’ll still be here when the tools change. You’ll still be curious, still capable of learning, still able to look at a problem and break it into pieces. The stack is temporary. The engineer adapts.

And maybe that’s enough. Maybe the goal isn’t to find an identity that never changes, but to find a way of working that makes change feel less like loss.

The terminal doesn’t care what language you type into it. It just waits, patient as ever, for whatever comes next.