by David Xiang
Managing a developer is very different than managing a codebase.
Shortly after transitioning into the startup world, I became a technical lead for the first time. As I fumbled my way through managerial responsibilities, I went through an amazing period of personal growth. Managing a developer is very different than managing a codebase. This first managerial experience was ultimately a failure in the practical sense, but it provided me with many useful lessons. This all took place at a tiny fitness startup in Los Angeles.
Hiring Without Desperation
We were desperate. Our engineering team, once numbering a healthy five developers, had dwindled down to two people. Like many other tiny startups, we were little kids fighting for Venture Capitalist attention with a laundry list of ambitious and poorly prioritized technical goals—goals that were now impossibilities. We weren’t making any money, and the future of the company hung on our CEO’s salesmanship and the sexiness of our next demo. Actually, desperate was an understatement.
Debt has both technical and cultural forms, both of which can crush you.
I ran through the gamut of difficult emotions during that time—anxiety, sadness, fear, doubt. Making any kind of decision while maintaining a calm and balanced state of mind is much easier said than done. We didn’t want our startup to die, and two engineers simply weren’t going to cut it. Product needed to be built and we needed someone to build it—anyone.
The first mistake I made was to hire too fast. At the time, I hadn’t fathomed the magnitude of my responsibility. The only thing on my mind was getting someone in the door who could code. I wasn’t too concerned about who that someone was. There are a million things going against you when you’re hiring for a startup. You’re strapped for cash, you can’t meet candidate expectations for salaries, and you have an uphill battle to face when selling the mission. Furthermore, the time spent recruiting takes you away from the four hundred other urgent things you need to be working on. Nevertheless, the recruiting needed to get done.
My core blunder was to prioritize speed over the long-term well-being of the company. If you’re feeling rushed by recruitment pressure, take a step back and slow, down. Hiring must be done with extreme care. If you don’t find the right candidate—even when the company is desperate—it means you have to keep looking. I saved a little bit of time up front, only to be overwhelmed later. Debt has both technical and cultural forms, both of which can crush you.
The second mistake I made was that I didn’t interview hard enough. I didn’t ask challenging questions, I didn’t dig, and I didn’t uncover the candidate’s true technical abilities until it was too late. I had nice-guy syndrome. During each interview, I was reserved and reluctant. I gave people the benefit of the doubt and utterly failed at my primary objective: to technically vet each candidate. After a few hours of easy questions and reasonably pleasant conversations, I rationalized that they should be good enough and we sent over offers.
Here is the lesson—do not give any technical benefit of the doubt to your candidates. You may be thinking: this candidate is probably having a bad day, perhaps I’m asking the wrong questions, or maybe they don’t interview well. While it’s perfectly normal for a candidate to have a bad day—I’ve bombed plenty of interviews—it doesn’t mean you shouldn’t dig as the interviewer. If you’re positive they’re technically competent, start getting to know them as a person. If they are technically incompetent, stop the interview and thank them for their time. If you didn’t get enough info, schedule an additional meeting to get the reassurance you need.
We were desperate for an engineer and we got one. Let’s call him Joe. Hiring Joe was a precursor to many months of stress and many more lessons learned.
No Scapegoating
It wasn’t long before I realized that hiring Joe was a huge mistake. I then began aiming all my negative emotions at Joe. The product was late because Joe wasn’t a strong developer. The technical debt was piling up because Joe couldn’t get familiar with the system. Having never been a manager before, it was convenient and natural for me to have these feelings. I guarantee that all of us have directed blame—even if it’s just in our heads—at our colleagues at some point. Eventually, I realized that Joe was completely my responsibility as his manager. No reasonable leader, under any amount of technical stress, should ever make a scapegoat of one of their team members.
With that said, let’s not tiptoe around the fact that Joe was a novice. Joe’s level of experience made him a dangerous developer. He was obviously a beginner, but he had coded enough to not need hand-holding. To be honest, I would have preferred Joe know less so I could have guided him more. Joe knew enough to run on his own, enough to push out commits. Unfortunately, these commits did more harm than good to our codebase. Joe couldn’t sense how his changes affected the system holistically, he didn’t check for edge cases, and his code would often melt down our existing features.
As Joe kept pushing out spaghetti code, I became increasingly bitter about the state of affairs. When our CEO complained to me about the latest malfunctions in the demo, I mentally abused Joe. Among peers, blame can be divvied up—no harm, no foul. However, on a team, the blame must always fall on the shoulders of the leader. If you accept the role, you accept the responsibility.
As a leader, you should never direct blame at your developers. When these feelings arise, always reflect on your core responsibilities. I eventually realized that I had neglected my duties to train and onboard my team. While some coders may come up to speed quickly, others will be slow and will make more errors. This is not their fault or their problem. I needed to take extra time and sit with Joe to make him an effective member of the team. Any blaming or complaining must be replaced by constructive actions.
Maintaining Clear Expectations & Goals
I failed to set clear expectations with Joe. I expected a lot from him, but unfortunately these thoughts only existed in my head. Without communicated expectations, you have nothing. While it’s normal for expectations to be a dynamic rollercoaster, it’s dangerous to have them be opaque—or even worse, nonexistent. In the best-case scenario, you should cover every expectation you have for your team and their work, from basic coding standards all the way up to career progression. Should we document our code? Is it cool to add in these libraries? When do we qualify something as done? What’s the big picture of my contribution over the next couple of years? What do you expect out of me as an employee? The answers to these questions must be clear and upfront.
Being close to our CEO at the time, I was in tune with our company’s goals, even as they fluctuated over time. Unfortunately, I took this for granted. In the beginning, Joe and I spoke very briefly about near-term objectives and our development process. I was anxious for Joe to jump into the code. I assumed he was a fortuneteller who would magically keep on my wavelength.
Keeping a group of professionals aligned over a period of time is no easy feat. Imagine a place where everyone knows what they’re working on, why they’re working on it, and how it fits into the big picture. Think that’s hard? Try keeping that going over a few years.
This kind of synergy is not the result of a simple new-hire meeting or onboarding document. It comes from clear expectations, consistent communication, and perpetual realignments. In a software company, the only constant is change. As we chugged along, I assumed Joe’s automatic alignment without verbalizing any expectations. If the CEO changed direction or asked us to scrap a feature, I assumed Joe would simply understand. When expectations aren’t clear and people don’t understand the why behind their tasks, quality work is impossible.
I had never set goals for Joe, and therefore I was never able to quantify his performance. I was naïve. I wanted him to learn new languages, pick up our frameworks, get pumped up on the mission, and follow all our design patterns. And I wanted him to do this all automatically, without a word from me. How could anyone understand all of that without clear, explicit leadership?
Expe
ctations play a crucial role in any kind of relationship. If you think a team member needs to spend two months getting better at C++, then tell them so and make it a written goal. If you expect a team member to document their work, make sure you consider the feature complete only when you see a polished Wiki entry. Expectations will always change over the lifetime of the relationship, but you should always be clear about them—never assume anything.
Constant Communication
Setting clear expectations is a lofty and abstract goal. It is implemented concretely via constant communication. I had always imagined a startup as a magical place. I had pictured a big LAN party where you could shoot the breeze, eat pizza, and rid yourself of petty bureaucracy— wasn’t that the dream? Everyone would vibe with each other, there wouldn’t need to be any meetings, and you could crank on code and drink Mountain Dew all day. While this might make for an interesting movie scene, it’s not what any successful company looks like—no matter the size.
During college, I loved the hacker way of doing things. I secretly enjoyed the marathon coding sessions, having a huge bag of chips next to my keyboard, and splitting a pizza with my friends. When I landed my first job, the politics and environment were a reality check. It felt mind-numbing compared to school; everything was slow, political, and it didn’t feel fun anymore. It was this that made startups seem so alluring. To me, startups were a way to relive the glory days of late-night coding.
Armed with an agenda and a purpose, a thirty-minute meeting turns into a highly productive exchange.
Obviously, the hacker mindset does not translate into effective leadership. I had always scoffed at one-on-ones with my managers. They were grossly unproductive for me during my first corporate job, so I felt no reason to conduct them with Joe.
Speaking as someone who used to dread meetings, I cannot stress enough how important they are. Since this experience, I have put in immeasurable time preparing and conducting effective meetings. The people who underestimate meetings are the ones who do not know how to utilize them. Armed with an agenda and a purpose, a thirty-minute meeting turns into a highly productive exchange. Furthermore, the one-on-one meeting is the cornerstone of management. It is where thoughts are shared, expectations aligned, and assumptions laid to rest. For anyone dipping their toes into management, take the time to read about how to conduct one-on-ones—any kind of management is doomed without them.
Vulnerability is OK
During this mismanagement ordeal, it took me far too long to bring it up with my CEO. The root cause was my personal fear of being seen as incapable; I didn’t want to be that guy who couldn’t handle the situation. I was the one who had hired Joe. I kept telling myself that I could make it work. That thought stemmed from a mix of fear and ego. What I learned is that it’s completely unreasonable to take the full weight of a difficult situation onto your shoulders. There will be times when you will need to ask for help, and somebody will gladly give it. When they look back to you, you’ll return the favor.
Conclusion
This is a common storyline for many first-time technical leads. If you go through a variation of this, stay attentive and conscious of the situation. Even a seemingly simple assignment of mentoring one person should be considered a serious endeavor.
My failure was bucketed into two categories. The first was my mindset. I never took responsibility as the lead. Joe was my scapegoat, the reason for our failed demos, and the cause of our spaghetti code. These issues were all things that I was accountable for. Replace blame with constructive action.
The second failure was communication. Joe and I were never clear regarding expectations. Don’t assume you can operate a company like a hack-week project. Put in extra effort to organize meetings and quickly share changes that affect other people’s work, and never assume your colleague “just gets it.”
21: Diva Developers [Daily Life]
When my product manager (PM) friend Jane told me about “diva developers,” I almost laughed out loud at the idea. Unfortunately, this wasn’t a joke. A single, unrestrained developer can disrupt the flow of entire teams. Jane’s story is a common one for many PMs.
A previous ecommerce company I work for created an unfortunate and unforgivable slang term to describe a certain type of developer. I’ve heard a lot of nonsense titles—rock stars, 10x coders, wizards—but never anything as sad as a “diva developer.” When I first heard the phrase in conversation, I wanted to believe it was a joke. Slowly but surely, though, I accepted my new Silicon Valley reality. There were some very entitled programmers who fit the term perfectly. These are programmers with a little extra ego, a little less empathy, who constantly put themselves at the center of any situation—they don’t move with the team; the team has to rotate around them. Their behavior is so bold and entitled that it negatively affects everyone they work with.
At a software company, the ultimate gatekeepers of progress are the developers. Sometimes the only thing we can do is play nice with them.
As a PM, I work with many different departments— design, engineering, strategy, analytics, marketing—and I do my best to get along with everyone. That’s part and parcel of the job. Yet regardless of how benevolent I think I am or how much others like working with me, my main concern boils down to one thing—progress. Progress is what product managers stress about. It’s what we complain to our friends about and it’s what keeps us up at night. Worst of all, it’s also the one thing we have minimal control over. At a software company, the ultimate gatekeepers of progress are the developers. Sometimes the only thing we can do is play nice with them.
On one of my first projects, I had to coordinate with a remote team of developers in China. Despite the logistical hurdles of limited real-time communication, time zone differentials, and the language barrier, we worked well together. Requirements were clearly communicated, development moved at a consistent pace, and there was a strong bond across the team.
Our mojo took a hit when our first local developer joined the team. Despite having a good thing going between our remote offices, the company was putting in an effort to co-locate its developers. I was scared of having our development split across the world, but I tried my best to count the potential blessings. Now I could actually speak with someone face to face and get more in the know with the daily tech. Little did I realize that this new developer was a diva and would soon be wreaking havoc on our dynamic.
Our new local developer, Martin, was obsessed with code quality. An extra pair of eyes on the codebase quickly turned into a constant bashing of our software; every remark out of Martin’s mouth was a barbed stab about how awful the existing implementations were. Instead of being constructive and striving to be part of the collective, Martin distanced himself from the other coders with continuous harsh, accusatory comments. A few weeks in, I was stressing out.
Regarding managerial duties, our remote developers were sitting alongside their technical leads and managers in China. Their development flow was humming smoothly, and they only communicated with me for product issues. We also had a local engineering department, but their attention at the time was focused on different product lines.
This proved to be tricky for our team, because Martin was assigned a local manager who was unfamiliar with our product and our style of development. His priorities were getting Martin up to speed and helping the company get engineers under one roof. Unfortunately, and understandably, this turned into Martin’s supervisor only looking out for him, while not fully considering his Chinese teammates across the world. During initiation, Martin’s boss informed me that Martin would be spending his first months onboarding and learning the system.
As his very first project, Martin decided to rewrite a huge feature of our application—shopping cart and checkout. The implementation was old, but it was working. I agree that it could have used some improvements, but I didn’t think it warranted an overhaul—if it ain’t broke, don’t fix it. There was a large amount of state and validation managed
by the back-end, which slowed things down for shoppers. Sure—in a perfect world, more of the state could have been managed by the browser front-end, which would only submit orders to our back-end if they were truly valid. Still, this was nowhere close to being an offensive experience for the customer. Yet Martin decided that he would take it upon himself—without telling his team—to rewrite the whole thing in JavaScript.
Unfortunately, none of us had any idea what Martin was working on until he was almost done. During his first couple of months, I assumed he was ramping up, fixing bugs, and working on standard get-up-to-speed tasks. No one expected him to rewrite one of the most important features in our product. No one had asked him to. Six weeks later, all hell broke loose when Martin was ready to push his code into production.
Right off the bat, our teammates in China were not happy. Martin had never shared anything with anyone about what he was doing. Suddenly, his teammates overseas found that he’d rewritten a huge part of the code behind their backs. They weren’t upset at the new code itself; they were upset that such a huge endeavor had been initiated without their knowledge. What good is a team of coders if the developers just work in silos? For me, I was borderline raging. Almost two months of development time had passed, and we hadn’t achieved anything. We’d made zero progress with larger initiatives, and the shopping cart feature looked exactly the same as it had before Martin joined. Worst of all, I now had to deal with a group of understandably disgruntled developers.