Skip to main content
arrow-leftBack to Blog

Avatars component for React that doesn't suck: Introducing Facehash

Facehash is an open-source, SVG-first React avatar component that generates deterministic faces from any string.

A
Anthony Riera
Avatars component for React that doesn't suck: Introducing Facehash

You spent weeks polishing your SaaS. The landing page looks incredible. The dashboard is clean. Everything feels premium.

Then users sign up.

And they don't upload profile pictures.

Suddenly your beautiful app is littered with empty circles, placeholder initials, and that default gray avatar you grabbed from some icon pack at 2am. Your product goes from "polished startup" to "weekend hackathon project" in one onboarding flow.

Sound familiar?

The default avatar problem in React apps

Here's a stat that won't surprise you: most users never upload a profile picture. They just don't. You can add a friendly reminder, a nudge during onboarding, even a popup that says "hey, upload a photo!" - they'll close it faster than a cookie consent banner.

The result? A comments section that looks like a witness protection program. A team page where everyone is a gray blob. A chat interface that screams "we didn't think this through."

And yet, avatars matter more than you think. They create visual hierarchy. They help users scan conversations. They make your app feel alive and populated rather than empty and abandoned.

Common avatar fallback solutions (and why they fail)

Gravatar? Great concept, limited adoption. Most of your users don't have one.

Random placeholder images? Confusing. "Wait, is that the same person who commented earlier?"

Just initials? Better, but you end up with a sea of colored circles that all look the same. Three users named "Alex" become visually indistinguishable.

Forcing uploads? Sure, if you want to tank your conversion rate.

Facehash: a React avatar component that generates unique faces

Facehash is an open-source React library that generates unique, friendly avatar faces from any string input.

The idea is simple: same input = same face, always. User "alex.chen@company.com" will always get the same avatar, whether they're on their phone, laptop, or that weird tablet they bought on impulse. No database storage. No API calls. No CDN. Just deterministic avatar generation that runs entirely in the browser.

import { Facehash } from "facehash";
 
export function UserProfile({ user }) {
  return (
    <div className="flex items-center gap-3">
      <Facehash name={user.email} size={48} />
      <span>{user.name}</span>
    </div>
  );
}

That's it. No configuration. No API keys. No "sign up for our avatar service." Just install and use.

Works with Next.js, Vite, and Remix

Facehash is a React package and is exercised in this repository with its React and Next.js entrypoints. It can be used in React applications built with tools such as Next.js, Vite, and Remix.

  • Next.js (App Router and Pages Router)
  • Vite
  • Remix
  • Any React setup, really

It declares no bundled runtime dependencies beyond its React/React DOM peer requirements (with Next.js as an optional peer for the Next entry). The face is rendered as inline SVG; CSS handles sizing and optional interaction/animation. There are no avatar image or font requests.

Using Facehash with shadcn/ui Avatar

If you're using shadcn/ui (or Radix), you probably want avatars that try to load a user's actual photo first, then fall back gracefully. Facehash does exactly this:

import { Avatar, AvatarImage, AvatarFallback } from "facehash";
 
export function SmartAvatar({ user }) {
  return (
    <Avatar>
      <AvatarImage src={user.avatarUrl} alt={user.name} />
      <AvatarFallback name={user.email} />
    </Avatar>
  );
}

If the image loads, great. If it doesn't (or the user never uploaded one), Facehash kicks in with a unique generated face. No more broken images. No more empty circles.

Customizing your avatar component

Facehash is customizable without being overwhelming. You control what matters:

// Different sizes
<Facehash name="user-123" size={32} />
<Facehash name="user-123" size={64} />
 
// Solid or gradient background
<Facehash name="user-123" variant="solid" />
<Facehash name="user-123" variant="gradient" />
 
// Custom colors to match your brand
<Facehash
  name="user-123"
  colors={["#FF6B6B", "#4ECDC4", "#45B7D1"]}
/>
 
// Reduce or disable the default dramatic 3D projection
<Facehash name="user-123" intensity3d="subtle" />
<Facehash name="user-123" intensity3d="none" />
 
// Hide the initial or hover interaction (both are enabled by default)
<Facehash name="anthony" showInitial={false} interactive={false} />

Real-world usage

We use Facehash in Cossistant, our open-source support widget. It shows up everywhere - in conversation lists, message threads, the dashboard. Both human agents and AI agents get their own deterministic faces.

It's one of those details users don't consciously notice, but they'd definitely notice if it was missing. The whole app just feels more finished.

Install Facehash in your React project

Install the package

pnpm add facehash

Import and use

import { Facehash } from "facehash";
 
function App() {
  return <Facehash name="your-user-id" size={48} />;
}

That's it

No configuration needed. No API keys. Just avatars.

Why we made this avatar library open-source

Honestly? Because this problem is too annoying to solve repeatedly. Every app needs avatars. Every developer goes through the same "what do I do when users don't upload photos" dance.

We packaged up our solution and put it out there. Use it however you want. Contribute if you're feeling generous.

Check out the documentation or grab the code on our Monorepo.

Your app deserves better than empty circles =).

Building a SaaS with React? We've got something for you.

Cossistant is an open-source support widget that works with Facehash out of the box. Add chat support to your app in minutes.

pnpm add @cossistant/react

Or sign up to get your API key and start building.

Get started free