My Approach

This page is about how I approach different aspects of working in tech, namely: Leadership and Engineering.

Leadership ^

I’ve played several leadership roles over my career from Guild/Community Lead to Team Lead to Head of Engineering while having many direct reports and no direct reports.

Throughout the years, my approach has evolved through observation, learning and old fashioned trial and error. I’ve succeeded and failed at roughly the same rate and both experiences are valuable for getting better.

My Leadership Approach in a Nutshell

I strive to develop a sustainable, people-centric culture within my teams and organizations.

That description is a bit vague. If I asked anyone "Do you value sustainability and a people-centric approach to leadership?" I can’t imagine them saying "No." In reality, though, I’ve faced plenty of opposition to my approach. So what’s the disconnect?

Breaking Things Down

Let me define “people-centric” and “sustainable”.

People-centric

By “people-centric”, I mean an approach where team members’ foundational needs are met and always remain a high priority. This is so important that sometimes we need to take a break from developing and shipping software to get back on track; a frightening concept for a lot of people I’ve encountered. But neglecting these needs for too long leads to turnover and turnover is ultimately more costly than that break.

I strongly believe in enabling my teams to solve every problem without me being hands-on and doing things for anyone. I never want to take away opportunities for people to apply their own expertise, gain new experiences or work on their goals, as long as reasonable time permits.

I serve my teams, they don’t serve me. Their success is my success.

Foundational Needs

This may not be a comprehensive list but here are some foundational needs I see for my teams, in no particular order:

  • Fairness in salary and other benefits for their market.
  • Psychological safety.
  • Concrete, plannable and attainable career growth opportunities*.
  • The ability to experience the impact of their work.

Without these things, I don’t feel the foundation of a team is complete.

* I like building career growth frameworks out of this Medium growth framework.

Communication

Though I didn’t list good communication as a foundational need, I do believe it’s paramount for success. I believe psychological safety encompasses good communication.

My approach to improving and fostering good communication includes, but isn’t limited to, the following:

  • Active listening is good for practicing empathy but it also enables productive conversations with disagreements. I.E., I can hear you, understand you and talk to you without agreeing with your interpretations or desired outcomes.
  • Stating our intentions and calling out our assumptions is the best way to save time, add clarity to conversations and keep communication safe.
  • Avoid dogma and take the time to teach, not tell, the reasons why we practice certain things or hold certain standards.
  • Direct communication is respectful. It doesn’t mean being blunt but rather being clear and on-topic. As mentioned, stating our intentions and calling out our assumptions greatly aids in direct communication.
  • Development is collaborative and effective when we talk about problems we have vs. solutions we’d like to implement. So many conversations start with solutions and skip over the problems entirely. This is confusing and it takes away opportunities for more people to apply their expertise.
Sustainable

By “sustainable”, I mean good for the long-term. I once had an Engineering Director who would often say “We have to move slow to move fast.” It was kind of funny, and often confused people, but I knew what he meant. We need to take the time to build solid foundations, if we want to build quality software, quickly, in the future.

Another aspect of sustainability crosses paths with the people-centric approach. That is the notion that it’s ok to slow down in order to make sure the foundational needs of the team are met.

Sustainability also manifests in other ways. To name a few:

  • Managing technical debt.
  • Up-skilling the team.
  • Handling the lifecycle of engineers on the team.

Managing technical debt requires a plan and a commitment from all stakeholders. It’s also a process of continuous education, trust building and shared prioritization.

Up-skilling the team is more crucial than it seems on the surface. When it coincides with career growth, it needs to align with an individual’s own goals. This contributes to the sustainability of the team personnel and retaining people.

When it comes to up-skilling in a more general sense, e.g., learning the latest in major dependencies, critical systems can be maintained with best practices for security and stability. Without these skills, the team can fall behind and parts of the system can become vulnerable or hard to maintain.

Lifecycle of Engineers

“Handling the lifecycle of engineers on the team” refers to the amount of time engineers can stay at the organization. I’ve yet to see any organization that offers endless, sustainable career growth opportunities and paths for their engineers.

A pattern often emerges when it comes to how long engineers will last. It coincides with how much expertise they gain in the technology used and/or if they’ve reached a point where a promotion would make them redundant.

My approach to this is perhaps different. I’ve often been offered a higher salary to stay with a company that I’ve already decided to leave. For me, salary has never been the reason to leave, and in my opinion, it’s a poor motivator for someone who may decide to stick around.

In my approach, there are a few key aspects to be aware of in your engineers‘ lifecycles:

  • At which level of skill or knowledge engineers start to leave.
  • The limitations of the technology, product or business you have.
  • Whether or not you can adopt appealing new technology to solve new problems.
  • Your organization’s engineering reputation.

If you know your limits, you can plan accordingly. Create onboarding and hand-over processes that accommodate your common cases. If you get a good sense of what people need when coming onboard and what they need to do when leaving, you can make the process as smooth as possible.

Also, I like to keep conversations open. With a good level of psychological safety, team members can speak openly about their needs for their career and whether or not your organization can meet them.

I always offer support to my team members when they’re ready to move on. I can’t stop people from doing what’s best for them but I can cheer them on and build a lasting relationship that strengthens our collective networks.

I would much rather have my former teammates sing the praises of their old team than to be indifferent or, much worse, outwardly negative.

Engineering ^

I’m an entirely self-taught software developer. I’m a good problem solver but in my early years, I re-invented the wheel many times and frequently embarrassed myself trying to talk about concepts that I didn’t understand.

Fast-forward to now and I’ve learned so much (the hard way). My current approach to software development has evolved over time and some core principles have emerged that define it:

  • Continuously learn and develop better software design skills.
  • Understand which languages, tools and frameworks are best for certain problems.
  • Identify and catalog the different problems I’m trying to solve when writing software.
  • Write code that’s easy to change.
  • Know my strengths and weaknesses. Know when to seek expert guidance. Keep in mind that I can learn from anyone at any experience level.
Software Design

Increasingly, I find myself most drawn to thinking about and learning better software design. I find it the most effective way for me to write quality code in whatever language and across programming paradigms, e.g., object-oriented and functional programming.

When I take software courses or crack open documentation, it’s great to learn about language or framework features, APIs, etc. but I try to pay more attention to the content that helps inform better software design.

Uncovering the Problems Being Solved

I’m using the term “uncovering” here because that’s what it feels like when I learn about features of languages, frameworks and tools. Similar concepts across different tool sets often have different names but exist to solve the same problems. Learning about which features exist in a framework is pointless, if you don’t know what problem they’re solving.

React has hooks” or “Go has concurrency primitives”, for example, are useless pieces of information, if you don’t know what problems they solve. In other words, these are solutions and solutions mean there are problems to understand.

Recognizing problems is key to quickly finding the canonical solutions in a given context or, if no solutions exists, providing the option to implement a proven solution from another ecosystem.

For example, I once had the opportunity to build apps with Elixir and it quickly became my favorite language. Many of the language features that make it so great, for me, forever changed the way I write my JavaScript code.

Writing Code That’s Easy to Change

I got the idea of writing code that’s easy to change (and so many other ideas) from Sandi Metz. Also, shout out to the absolute legend, Sandi Metz. There’s a lot to unpack in my interpretation of this concept…

To me, writing code that’s easy to change means it has a few qualities:

  • The code largely follows SOLID principles. I find these principles apply to both object-oriented and functional programs but how they are applied is different.
  • The code is easy to read and understand. Not just single classes or modules but also the interactions between objects and/or functions of different types. Too much indirection, for example, gets me lost or requires me to store a lot of information in my brain all at once.
  • The code follows established conventions. This helps ensure experts can quickly parse it and it helps newcomers stay on track.

Sandi talks about change as an indicator that people are using your software. If you plan for change, you’re also planning for success. You’re helping your future self and your future teammates.

It’s with this goal in mind that I measure the quality of my code now by asking myself “Is this code easy to change?” and it’s a good feeling when I can answer a resounding “Yes.”

Testing

I haven’t mentioned testing in my approach because it’s such a large topic, I’ll write about it more in thoughts. It’s worth sharing a few quicks notes, though:

  • I will always test my code.
  • There are more than a handful of useful types of tests and understanding which type of test to write for a given part of the system is important.
  • I don’t always find test-driven development a good approach. I find there are times when it’s good and times when it’s pointless.
  • I try hard to practice testing minimalism, a concept I picked up from, you guessed it, Sandi Metz.
Accessibility and Ease of Use

I feel quite passionately about the topic of accessibility. I’ve annoyed many product managers and graphic designers over the years. It’s my consistent experience that accessible software is easier to use for everyone. I try to push for first-class accessibility in features at every organization.

Taking inspiration from the ease of use accessible software brings, I highly value, and encourage the development of, libraries and APIs that help engineers navigate their capabilities through the interface rather than only provide some documentation. Things like Rust’s compiler and GraphQL’s error messages come to mind, among many other great examples.


Thanks for reading about my approach. I’ll be sure to add more thoughts on my approach to Leadership and Engineering to the blog, as time goes on.