08 Oct 2023

[Building Engage] #4. Avatars

Features like avatars look trivial in products with user profiles, but most times, they are not. (Is anything actually trivial?). It’s even more interesting, as with Engage, when users can’t upload their profile pictures themselves. Where do we get one from?


If you are familiar with this, this would be your answer as well. Gravatar is one of the oldest forms of getting people’s profile pictures. Make a request with the person’s [encrypted] email address as a parameter and get a profile picture in return.

const hash = md5(email)
return `<img src="https://www.gravatar.com/avatar/${hash}">`

There are two major drawbacks though.

  • Gravatar uses email address as the unique identifier. This means if you don’t have the user’s email (a product that doesn’t collect user’s email address for example) there is no way you can get the user’s profile picture.
  • The user needs to have set up that email on Gravatar. While a lot of people have their emails set up on Gravatar, some people do not. This means having a user’s email does not automatically guarantee that they will have a profile picture on Gravatar.

Default/fallback image

Gravatar provides a solution to the second challenge – if the profile does not exist. You can provide a fallback image (as a URL) that is displayed instead.

const hash = md5(email)
const fallback = encodeURIComponent('https://my.app/images/default.png')
return `<img src="https://www.gravatar.com/avatar/${hash}?d=${fallback}">`

This is good. But it means every profile with no gravatar will have the same default image. If you are Facebook or Twitter (X), that may be fine. For us, I wanted some uniqueness. Gravatar has a way to generate unique defaults but I am not a fan of the designs. Are there alternative avatar services that can be used instead of Gravatar or as a fallback for Gravatar? A lot. But what are we looking for to start with?

Service Checklist

I created a checklist of what we want in a service.

  1. It should be able to use email as an identifier, i.e., pull the avatar attached to the user’s email.
  2. Emails are optional user attributes on Engage, so if it doesn’t exist, the name (first or last name) should be used. Usernames would have been the next best thing but usernames are not standard attributes on Engage. Names can’t be used to pull a profile picture but we can use it to create an avatar of initials.
  3. If the user has an email but it doesn’t return a profile picture, get initials from the email and use that to create an avatar.
  4. If the profile has no names (names are optional as well), generate a unique random avatar using the user’s ID. We do not want a default profile picture for all users with no email or name.


I love Unavatar! And for many reasons. It’s open source, has simple implementation, and pulls profile pictures from many places.

Just append the user’s username, email, or domain to unavatar.io and that’s it

<img src="https://unavatar.io/engage.so">

Unavatar checks preference 1. It doesn’t check preference 2 but has a fallback option so we can get an initials avatar service as fallback. It doesn’t check preference 3 as well but we can use a different service as a fallback if the user has no name.

Vercel Avatar

Vercel has an avatar service that generates beautiful gradients and can generate initials from a text parameter. We can’t use it to pull profile images using emails as reference but it is a perfect fallback for other services because it can generate a unique avatar from an ID and also generate a unique avatar with initials.

Generating a unique [gradient] avatar from the user’s ID works well as fallback for Gravatar and Unavatar but initials avatar does not work for Gravatar. The unique avatar can be generated in PNG format (default) but the initials avatar has to be SVG. Gravatar does not support SVG as a fallback image.


Outline has Tiley, an avatar service that solves the SVG problem. We can generate an initials avatar in PNG, JPG, or even SVG format.

Tiley can’t generate a unique avatar without the initials. And if we don’t want to go with Vercel Avatar as a fallback for unique avatars when we don’t have the user’s email or name, then we can use another service for unique avatars.

Boring Avatar

My recent favorite is Boring Avatars. I love the styles and there is a documentation on how to use it as a service.

<img src="https://source.boringavatars.com/${variant}/${size}/${id}

What should I use?

As with everything, it depends. What user attributes do you have? Email? Username? Name? Do you mind the same default image for all users? Or do you want something dynamic? What design style? Can users upload their profile pictures themselves?

In the end, we went with Boring Avatar for profiles without email or name and Gravatar for profiles with email or name with Tiley as a backup for initials. Earlier versions of Engage used Unavatar and it will always be my first choice. However, even though I doubt we would ever hit it, I was [subconsciously] conscious the hosted version is rate-limited and I didn’t want to self-host yet another service.


Looking for a simple marketing automation tool to automate your customer onboarding, retention and lifecycle emails? Check out Engage and signup for free.


My name is Opeyemi Obembe. I build things for web and mobile and write about my experiments. Follow me on Twitter–@kehers.


Next post: Re: Passkeys