All posts by Jonathan Stassen

When do you need useMemo (and when don’t you)

It’s confusing when we should use useMemo and when we shouldn’t.

useMemo isn’t free $

useMemo comes with a small cost. So we should understand when it’s a benefit, and when it doesn’t provide any value.

  • Small usage in RAM to memoize & remember the resulting value
  • It costs a small cpu cycle to loop over & compare the dependency array & run internal fn of useMemo

So we should be smart when we use it.

useMemo isn’t always needed

useMemo isn’t needed in certain cases. For example, casting something to Boolean, or doing simple math isn’t an expensive operation and returns a primitive like “boolean” or “number”. These value will always be the same every time they are re-render run 

true === true and 5 === 5.

Conversely, an array or object don’t have equality,

 [] !== [] and {} !== {} and new Date !== new Date.

Two tests of if you need useMemo

  1. Is the calculation to get the value is complex (looping, calculating, initializing a class)?
    • Or is it cheap (comparisons of numbers, boolean, casting types, simple math)
  2. Is the returning complex value (object, array, fn, or class)?
    • Or is it a primitive value that is simple to compare (number, boolean, string, null, undefined)

Examples

  const date = useMemo(() => Date.parse(isoDateString), [isoDateString]);

We should use useMemo

  1. 🛑 Initializes the Date class
  2. 🛑 Returns a Date Object, which is not a primitive

  const isAdmin = useMemo(() => runExpensiveSearch(accounts), [accounts]

We should use useMemo

  1. 🛑 Runs an expensive function to get the value
  2. ✅ Returns a primitive value

In cases where it’s neither an expensive calculation nor a complex object, useMemo isn’t necessary.


-  const isArchived = useMemo(() => Boolean(process?.deletedAt), [process?.deletedAt]);
+  const isArchived = Boolean(process?.deletedAt);

We don’t need useMemo

  1. ✅ Casts to a boolean which is a cheap operation
  2. ✅ Returns a primitive value

-  const numberOfAccounts = useMemo(() => accounts.length, [accounts]);
+  const numberOfAccounts = accounts.length;

We don’t need useMemo

  1. ✅ Getting the length property is cheap
  2. ✅ Returns a primitive value

Just remember the two tests

  • Is it complex / expensive function?
  • Is the value not a primitive?

What about useCallback?!

I’m so glad you asked! The principles are similar. In general, all callback functions should be memoized via useCallback. Functions are considered a non-primitive value thus never have equality unless we memoize them via useCallback.

(Cover Photo: Feldstraße Bunker, Hamburg, Germany – Jonathan Stassen / JStassen Photography)

Naming Booleans: Readablity with Affirmative Boolean

As a rule of thumb: Naming booleans in the affirmative

One of the most challenging aspects of software development is choosing the good names for variables. This is particularly true when it comes to Boolean variables.

“Naming things is hard.”

– Some Software Developer

Affirmative names are those that start with words like is, has, or can which clearly indicate that the variable is a Boolean.

Affermative Booleans Variables

Our goal is to be consistent in the naming & to keep it readable — almost like a sentence. Take a look at these examples, “Is logged in” or “has favorites” and “has no favorites”.

AffermativeNegative
isLoggedIn!isLoggedIn
isEmpty!isEmpty
hasFavorites!hasFavorites
canEdit!canEdit
Great Boolean Variable Names

Reading these like a sentence is natural. “Is logged in” or “can not edit”. There is only one nation flip in your mind you must do when reading the negative cases.

Negative Booleans Variables

Now, let’s consider what happens when we deviate from the Affirmative Approach and use negative names.

Affermative?Negative?
notLoggedIn!notLoggedIn
isNotEmpty!isNotEmpty
hasNoFavorites!hasNoFavorites
canNotEdit!canNotEdit
Confusing Boolean Variable Names

Our negative cases create a double negative! 😯

Try to read that negative statement as a sentence. “Does not have no favorites?” I think I know what that means, but that feels like an awkward way of saying “hasFavorites”.

The problem with negative named booleans is that they introduce the potential for double negatives. The Affirmative Booleans approach is more straightforward to mentally parse.

Conclusion

In general, naming Booleans in the affirmative is a practice that can significantly improve code understandability and maintainability.

Avoid no, and not, and other words that create the possible of a double negative when the boolean is flipped.

Naming things is hard, but naming boolean variables in the affirmative is a simple, yet effective way to help improve your code readability. Your future self and your teammates will thank you for it.

If you like thinking about naming, you may also enjoy thinking about pagination naming.

(Cover Photo: Factory in Sneek, Netherlands – Jonathan Stassen / JStassen Photography)

Migrating a codebase to enable strictNullChecks

Migrating a codebase to enable strictNullChecks can be tricky.

TypeScript’s strictNullChecks is a powerful compiler flag that enhances code safety by detecting potential null and undefined values at compile time.

There is some interesting discussions on migration, but to me none of them quite were satisfying:

I believe there is another incremental way

Let’s use this code as our example. With strictNullChecks : false it will not errors. With it strictNullChecks: true it will.

type User {
  email?: string
}

function getUserEmail(user: User): string {
  return user.email; // user.email might be null or undefined
}

Simple enough to fix. But in a large codebase we may have hundreds of these errors, and many will be much more complex. In my teams codebase, we had north of 500 errors and the count was unintentionally increasing.

Two Goals:

  • How might we incrementally resolve existing issue?
  • How might we prevent additional issues creeping in?

Enable strictNullChecks → Mark errors with @ts-expect-error → Setup eslint rule → Monitor with esplint

1. Enable strictNullChecks

Enable strictNullChecks is the natural first step in migrating. Adjust the compilerOptions flag for strictNullChecks in your tsconfig.json.

{
  "compilerOptions": {
    "strictNullChecks": true,
  }
}

By setting strictNullChecks to true, the TypeScript compiler will perform stricter checks on nullable values, reducing the possibility of null or undefined-related runtime errors.

2. Mark all existing errors with @ts-expect-error

There were likely be a large number of strictNullChecks exceptions in an existing codebase. Realistically, we probably can’t fix them all right away. We can use typescript’s @ts-expect-error comments before every instance of an error to temporarily suppress strictNullChecks errors per line.

function getUserEmail(user: User): string {
  // @ts-expect-error: 🐛 There is a null/undefined issue here which could cause bugs! Please fix me.
  return user.email;
}

This tells the typescript compiler that we’re aware of the error and currently expect it. We are marking them for further consideration during the migration process.

As an aside: @ts-expect-error is generally preferred over @ts-ignore. 
@ts-expect-error - Is temporary. Once the issue is fixed, typescript will remind us we can remove the @ts-expect-error. 
@ts-ignore - Is more permanent. suppresses the error and doesn't expect it to be fixed later.

At this point you could finish here!

However I recommend leveraging eslint to also keep us accountable.

3. Using eslint to highlight lines needing a refactor

While @ts-expect-error comments provide a temporary workaround, it’s important to gradually eliminate their usage to achieve the full benefits of strictNullChecks. Relying on @ts-expect-error extensively can undermine the benefits of type safety. We should flag these as not-ok in our code base. I would like to have a red or yellow squiggle marking them.

With eslint we can configured the @typescript-eslint/ban-ts-comment to warn on the usage of an @ts-comment. This further makes it clear in our editors that @ts-expect-error is temporary and should be fixed.

Example .eslintrc.json:

{
  "overrides": [
    {
      "files": ["*.ts", "*.tsx"],
      "rules": {
        "@typescript-eslint/ban-ts-comment": [
          "warn", {
            "ts-expect-error": true,
            "ts-ignore": true,
            "ts-nocheck": true,
            "ts-check": true
          }
        ]
      }
    }
  ]
}

4. Using eslint to discourage new issues

To take the enforcement of code quality a step further, we can introduce esplint—a tool that specializes in tracking and managing eslint warnings counts and enforcing that the count should only decrease. By leveraging esplint, we can keep a count of @ts-expect-error occurrences in our codebase. This count also serves as a metric to gauge progress during the migration. The goal is to steadily reduce the count, indicating a decreasing reliance on @ts-expect-error comments – thus an increase of strictNullChecks and an overall improvement in code quality.

Migrating a codebase to enable strictNullChecks

From here the codebase is ready to be slowly refactored. We encourage our team as they are working on a stories that touche code near one of these error, to take the time to refactor and cleanup the null checking.

This refactoring might involve implementing better error handling mechanisms, like using TypeScript’s union types, optional chaining (?.), or nullish coalescing operator (??).

Conclusion

Migrating a codebase to enable strictNullChecks can significantly improve code quality and enhance overall code quality. I believe by following the this pattern is a pragmatic and straightforward approach to enabling strictNullChecks. With diligent effort, we can all embrace strictNullChecks and enjoy the benefits of reduced runtime errors and write more code with confidence.

(Cover photo: White Sands National Park, New Mexico – Jonathan Stassen / JStassen Photography)

What makes a meaningful standup update?

Hey there! I know it can be difficult to know what to say in standup. One of the most important things you can do to keep your team in the loop is to share a meaningful standup update on your progress. Think of it like a relay race – each team member needs to know where the baton is, how fast it’s moving, and whether there are any obstacles ahead.

When I enter standup and giving my update, I like to ponder: “What info can I give to the team that might be meaningful for a standup update?”

Tips for sharing meaningful standup updates

  1. Update the team on your current work status
    Let your team know how close you are to meeting milestones, deadlines, and if you’ve encountered any issues. For example, “I’m 85% complete with the License/phone selector for site settings and should have it ready for review by tomorrow morning.”
  2. Communicate any changes that may impact others
    Let your team know of any changes to your work that may impact or unblock the work of others. For example, “I’ve finished the API bits for both site and account phone/license, which should now unblock the UI stories for the rest of the team.”
  3. Customize your updates
    Tailor your updates to your team members’ interests and needs. For example, provide more details on a technical challenge for a team member who’s interested.
  4. Be proactive in sharing updates or asking questions
    Don’t wait for someone to ask for an update. For example, “I wrote up a bug I believe I noticed a bug in production, I would like to see if we should address it now or a future sprint.”
  5. Provide context
    Share not only what you’ve done but why you’ve done it. Providing context can help non-technical team members better understand the value it brings, and how it fits into the overall vision. For example, “I’ll be starting work on the date pickers, this is part of the new reporting view we’re building.”

Why do Good Standup Updates matter, you ask?

Well, here are a few reason:

  • Keep your team up-to-date
    Regular updates help everyone stay informed about the progress of the project and any potential roadblocks.
  • Identify and address issues early
    Sharing updates on any issues or challenges you’re facing can help your team address them early on, preventing them from becoming bigger problems down the line.
  • Foster team cohesiveness
    Sharing updates can help your team understand each other’s work and goals, leading to better communication and collaboration towards a shared vision.

“The single biggest problem in communication is the illusion that it has taken place.”

– George Bernard Shaw (1856 to 1950)

So, the next time you’re in a standup meeting, don’t just rattle off a list of tasks you completed – instead think of your standup updates like a baton in a relay race – an opportunity to keep everyone informed, stay on track, and work together to reach the finish line.

Ask yourself: “What info can I give to the team that might be meaningful for a standup update?” and you’ll build a strong team culture that values open communication and collaboration, leading to more productive and successful projects.

Become an Effective Software Engineering Manager – Book Review

Become an Effective Software Engineering Manager is an essential guide for learning to grow and lead engineers.

This is the single best book I’ve read on what it means to be a great Engineer Manger. It’s an enjoyable and honest read.

Become an Effective Software Engineering Manager Book Cover

Rating

(Higher is better, 5 is neutral)

  • Would I recommend? 10 / 10
  • Did I learn anything? 10 / 10
  • Did I learn anything I can apply? 9 / 10
  • High Information density? 8 / 10
  • Would I re-read? 9/10

Buy Become an Effective Software Engineering Manager on Amazon

Become an Effective Software Engineering Manager Overview

The author will take you on a journey from day one to being a central influencing helping your team be the effective and impactful.

The book is broken down into 3 major sections: Managing Yourself, Working with and Managing others, Working with Teams and the Organization at Large.

Who should read Become an Effective Software Engineering Manager?

Certainly every Engineering Manager and Head of Engineering. This could be a playbook for creating a philosophy around great management.

Senior Engineers who are considering Engineer Manager route or want to build empathy with an Engineer Manager’s role.

My main takeaways

Being organized is very key to being a great manager. Use your calendar, email, reminders, and notes effectively. Specifically automated reminders will give you super powers.

You have two options for leading: The Stick or The Carrot. The Stick driving everyone forward with pressure & deadlines. The Carrot by motivating & aligning on mission.

There is a hierarchy of needs in the workplace. First two are Physiological (pay & benefits) and Safety (job security & environment. These two we have control over as manager, but don’t lead to long term job satisfaction. The next three are Belonging, Esteem, and Self-actualization. As managers we can contribute to these fulfilling items by finding opportunities that align with a reports interests.

There tends to be two developer archetypes: Cathedra Builders and Bazaar Browsers. Those that want to go deep and be a subject master, building towards perfections; and later are those that desire for exciting new things and never want to be stagnant. Each have their space in an organization and both are motivated in their own ways. Don’t try to fit one in the others role for long if you can help it.

Delegation has a range of levels of oversight. From no oversight to showing another how to do a task. Closing the right level of delegation depends on the task and the individuals capabilities.

If you liked this book, next I’d recommend:

Going deeper on team culture: Elegant Problem
Going deeper on leading with positive impact: Multipliers
Going deeper on project management: Waltzing with Bears

Debugging Teams – Book Review

Debugging Teams is a short, clean, and to the point read. It’s a great book to pick up, read a page or two & set down and ponder. Every section speaks lightly, yet bluntly about team culture & being a great team member.

Debugging Teams Book Cover

Rating

(Higher is better, 5 is neutral)

  • Would I recommend? 9 / 10
  • Did I learn anything? 8 / 10
  • Did I learn anything I can apply? 7 / 10
  • High Information density? 8 / 10
  • Would I re-read? 7/10

Buy Debugging Teams on Amazon


Debugging Teams Overview

Debugging Teams speaks honestly and cuts to the chase. It provides practical advise with how to work with (and around) bad culture and defines what good culture looks like.

It reminds us that good team culture starts with ourselves. We have to be humble to grow ourselves to be an example of what good culture is.

Debugging Teams sets that bar of what that good team culture should looks like and thusly what bad culture looks like.

Who should read Debugging Teams?

Pretty much everyone! Specifically leadership, managers, and junior to senior devs.

I consider this essential reading for any of team member as an introduction to thinking about team culture.

My main takeaways

Culture is important from day 1, bad culture from one teammate infects an entire team and pushes away good talent. It’s hard & nearly impossible to override one toxic teammate with many good ones, it just doesn’t work.

Therefor don’t tolerate having the Brilliant Jerk on the team. They aren’t worth it. They set bad culture and diminish the team around them.

Be the example of the culture you’d like to see, be humble, you likely have faults as well. We need to be aware of our own ego.

If you liked this book, next I’d recommend:

Going deeper on team culture: Elegant Problem
Going deeper on leading with positive impact: Multipliers
Going deeper on project management: Waltzing with Bears
Going deeper on managing a team: Become an Effective Software Engineering Manager

Favorite Quotes

“Software development is a team sport”

“If you spend all your time working along, you’re increasing the risk of failure and cheating your potential for growth”

“Relationships always outlast projects”

“Understand the difference between constructive criticism of someones’ creative output and flat-out assaults against someone’s character. […] If you truly respect someone, you’ll be motivated to choose tactful, helpful phrasing.”

“Your self-worth shouldn’t be connected to the code you write – or any project you build.”

“When you stop learning, you get bored. It’s really easy to get addicted to being a leading player; but only by giving up some ego will you ever change directions and get exposed to new things. Be willing to learn as much as teach.”

“Admitting you’ve made a mistake […] is a way to increase your status over the long run.”

“A ‘strong culture’ is one that is open to change that improves it, yet is resistant to radical change that harms it”

pg 31

Get Together – Book Review

I rather enjoyed Get Together and recommend it often to my friends who find themselves leading communities. I’ve build several communities and indirectly followed some of the exact same patterns. Having this book as a guid would have been a huge help. Reading through it I’ve learned new ideas for forming strong communities.

Get Together Book Cover

Rating

(Higher is better, 5 is neutral)

  • Would I recommend? 8 / 10
  • Did I learn anything? 7 / 10
  • Did I learn anything I can apply? 7 / 10
  • High Information density? 6 / 10
  • Would I re-read? 8/10

Get Together on Amazon

Get Together Overview

There is a bit of a science to building strong thriving communities, and Get Together shares some of those patterns that can be implemented in nearly any scenario.

Get Together shares what they call the 3 phases of growing a community: Spark the Flame (Getting things started), Stoke the fire (Building strong community), Passing the torch (Empowering the next set of leaders)

Who should read Get Together?

Anyone who is either looking to, or already leading a group. Be it either social or in a work environment. If you are looking for ideas of how you might get your group off the ground or stoke your group to grow to the next level, this is a good read.

My main takeaways

Find core, excited people in your community and empower them to get involved and participating.

You can build a community about anything your passionate about, even a cloud fan group!

Make gatherings Purposeful, Participatory, and Repeatable.

Create a space to talk and provide prompts to keep conversation going.

Give members a sense of identity, giving tokens and ownership.

Empower the next set of leaders. You don’t need to lead forever.

If you liked this book, next I’d recommend

Building a multiplier team culture: Debugging Teams

Example of strong company culture: Creativity Inc.

What is a Feature Flag?

Perhaps you’ve heard of Feature Flags, maybe you haven’t. What is a flag? What do they solve?

We value low stress deploys that are independent of feature launching. We value working in small batches enables us as a team to be agile to priority changes.
We value these things so that we may continuously delivering the highest value product to our users of our application.

Feature flags are a tool that help us meet these values.

We utilize Feature Flagging as a mechanism to Continuously Deliver product with both confidence and safety. A partially built feature can live behind a flag instead of a feature branch. Feature branches are worthwhile avoid to eliminate merge conflicts, reducing work, and integrated.

A feature flag create two universes that live in parallel

A feature flag creates two universes that live in parallel for a period of time – one with the feature, and one without. Ultimately when the feature is live, the flag will be removed.

Life cycle of a feature flag

A flag is short lived and is removed after the feature is live.

📋 Flag added →
🏗️ Feature incrementally built behind flag →
👷 Feature tested with flag enabled →
🚀 Feature enabled in Production →
🧹 Flag and old code removed

If we want to use a flag more long term, it’s more likely an application setting. Feature Flags should be temporary.

What does a feature flag look like in practice?

A flag is essentially an if statement around a body or line of code. Let’s say we’re adding a dark mode to our site and want to give users a setting to use it, but it’s going to take a while to build theme the entire site. We could make a very simple flag to hide it from the settings page until it’s ready.

const darkModeFeature = false;

const SettingsPage = () => {
  return (
    <div>
      {darkModeFeature && <Checkbox label='Dark Mode'/>}
      <Checkbox label='Send me emails'/>
    </div>
  );
}

This flag is inline and in the same file, It can be a good idea to centralize flags into a single file like config/featureFlags.ts or use services like LaunchDarkly, Split.io, or other services.

Levers can be use to enable a feature flag

Depending on your service you use, or how you implement your flagging, flags can be automated to have to be triggered on / off by different signals. For example:

  • Deployment Environment (Development, Staging, Production)
  • Comparing the current date to launch date and time.
  • Set of User ID
  • User Role
  • A small percent of users

Each have their uses and potential benefits and the options will widely very by your creativity and application. However most common will likely be the deployment environment.

Further Reading

Multipliers – Book Review

Multipliers captures one of my key values: Investing in others and empowering them to reach their full potential. I was very excited to find a book aligned with that very value, and it did not disappoint.

Rating

(Higher is better, 5 is neutral)

  • Would I recommend? 9 / 10
  • Did I learn anything? 8 / 10
  • Did I learn anything I can apply? 8 / 10
  • High Information density? 7 / 10
  • Would I re-read? 7/10

Buy Multipliers on Amazon

Multipliers Overview

Multipliers compares communication that build and unlock the potential of others and contrasts it agains communication that diminishes. By the end of the book you’ll have many tools to identify your strengths as well as weaknesses in which you can grow to better build your team up.

As a book, Multipliers feels a bit “corporate self-help” in nature akin to Enneagram or DiSC. At times the sections felt light and wordy. Nevertheless the ideas are fantastic and solicit self-reflection. It has many tips and examples to help transition diminishing patterns to multiplier patterns.

Who should read Multipliers?

Everyone could learn about themselves from Multipliers. Specifically managers, mentors, and leaders without a doubt should read Multipliers.

If you’re someone who leads people or aspires to lead, Multipliers will help you consider your blind spots you could level up to become an even more impactful leader.

My main takeaways

Even the best leaders can accidentally Diminish others around them.

Even though it comes form a good place, being too supportive & available can cause others to rely on you to ‘save the day’ and thus diminish their growth opportunity. Being less available and trusting challenges others to grow.

Hand back the pencil. Give the power back to others after you’ve contributed a thought. Don’t solve all of it, include them.

If you liked this book, next I’d recommend

Building a multiplier team culture: Debugging Teams

Example of multiplier company culture: Creativity Inc.

10 Great Topics for Engineering All Hands

What are good Topics for Engineering All Hands?

Bringing together an engineering team is something we all can agree we should be doing. But how do make sure it’s not a waste of time?

We might ask many questions that will guide us in the direction to find topics for engineering all hands.

  • What updates are value for the team?
  • What topics should be presented?
  • What makes the teams feel involved or appreciated?
  • What information might the team not get elsewhere?
  • What would help align the team in a shared vision?
  • What formats make the most sense to present in?
  • What might excited the team?

Your team will be unique and will always be evolving to find new patterns of topics that gel well and are provide the most value. Ask your team what they would find valuable, experiment and try new things.

Here are several ideas of my ideas for topics for engineering all hands to get you started in running great engineering all hands.

10 Great Topics for Engineering All Hands

1. Impact of what has been built

This could be backed with numbers like sales, hours saved, etc.

Customer stories how they using what the team has been building. This could even involve bringing in real customers to meet the team and share their real life usage of the product.

2. User Feedback about what we’ve been built.

Similar to impact, however this might be reviews, tweets, emails, or feedback of what users are saying about the product we’re building.

3. Vision of why and what we’re building across teams at high level.

What are the business goals that we’re trying to meet?
How are team roadmaps satisfying those business needs?
What sort of things will be building over the next 3, 6, or even 12 months?

4. Light technical deep dive

Share big picture technical demos. This could be big projects, or ones that are good general knowledge sharing. Even though the Engineering All-Hands will mostly have technical folks, refrain from deep-diving too far, that might be better for a technical show-case. We have so many other things to share during the All Hands!

5. Updates around pay / careers / hiring

Are we planning on hiring team members?
What level are we hiring for and for which teams?
Are there updates about how careers are evaluated/structured?

6. Vision of how we want to be structured and grow as a product org

What are the Engineering Orgs vision of who we want to be, what our values are? How do we better ourselves and improve so that we might be one of the best Engineering Ors.

7. Opportunities to make an impact

Share needs that are across the entire Engineering organization as opportunities to get involved.

Are you forming a think tank group about coding standards? Want to form a team to plan an Engineering Off-Site Outing? Looking for volunteers to brainstorm a new product?

8. Recognition across all teams

What wins do teams have? Some may be customer facing, others interesting technical accomplishments. It’s important to recognize an entire team, not just individuals.

9. Promotion announcements

Celebrate team members who are growing! Promotions aren’t handed out lightly, with a good career band system they are tangible accomplishments. We should be proud and celebrate them!

10. New hire intros

This may have been also done at the Company wide level or at the team level. This is an opportunity to have fun intro at a technical level and across the entire Engineering organization.

Further Thinking

Who should be presenting at an Engineering All Hands?
How might presentation roles be shared?
How might an Engineering All Hands be interactive?
How do you Host a Great All Hands?