
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Deterministic avatar faces from any string. Lightweight, interactive, pure CSS. Works with any framework.
Deterministic avatar faces from any string. Lightweight (~3KB gzipped), zero dependencies, works with React 18/19 and Next.js 15/16.
npm install facehash
import { Facehash } from "facehash";
<Facehash name="john@example.com" />
Same string = same face. Always.
Generate PNG avatar images via API endpoint — perfect for emails, Open Graph images, or anywhere you need a URL.
// app/api/avatar/route.ts
import { toFacehashHandler } from "facehash/next";
export const { GET } = toFacehashHandler();
Then use it:
GET /api/avatar?name=john@example.com
GET /api/avatar?name=john&size=200&variant=solid
Returns a PNG image. Cached for 1 year by default.
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | Required | String to generate face from |
size | number | string | 40 | Size in pixels or CSS units |
colors | string[] | - | Array of hex/hsl colors |
colorClasses | string[] | - | Array of Tailwind classes (use instead of colors) |
variant | "gradient" | "solid" | "gradient" | Background style |
intensity3d | "none" | "subtle" | "medium" | "dramatic" | "dramatic" | 3D rotation effect |
interactive | boolean | true | Animate on hover |
showInitial | boolean | true | Show first letter below face |
onRenderMouth | () => React.ReactNode | - | Custom mouth renderer (replaces initial) |
enableBlink | boolean | false | Enable random eye blinking animation |
<Facehash
name="alice"
colors={["#264653", "#2a9d8f", "#e9c46a", "#f4a261", "#e76f51"]}
/>
<Facehash
name="bob"
colorClasses={["bg-pink-500", "bg-blue-500", "bg-green-500"]}
className="rounded-full"
/>
<Facehash name="charlie" intensity3d="none" variant="solid" />
<Facehash name="diana" showInitial={false} />
Add a subtle, chaotic blinking effect to make faces feel alive:
<Facehash name="alive" enableBlink />
The blinking is pure CSS with randomized timing per eye — each eye blinks at different intervals for a natural, chaotic effect.
Replace the initial letter with any custom component:
import { Facehash } from "facehash";
import { Spinner } from "./spinner"; // Your loading spinner
// Show a spinner as the "mouth"
<Facehash
name="loading"
onRenderMouth={() => <Spinner size={16} />}
/>
// Custom icon
<Facehash
name="bot"
onRenderMouth={() => <BotIcon className="w-4 h-4" />}
/>
// Combine with blinking for a "thinking" avatar
<Facehash
name="thinking"
enableBlink
onRenderMouth={() => <Spinner size={12} />}
/>
For image avatars that fall back to Facehash when the image fails:
import { Avatar, AvatarImage, AvatarFallback } from "facehash";
<Avatar style={{ width: 40, height: 40, borderRadius: "50%", overflow: "hidden" }}>
<AvatarImage src="/photo.jpg" alt="User" />
<AvatarFallback name="john@example.com" />
</Avatar>
AvatarFallback renders a Facehash by default. For initials instead:
<AvatarFallback name="John Doe" facehash={false} />
The facehash/next export provides a route handler factory for generating avatar images server-side. This is useful for:
// app/api/avatar/route.ts
import { toFacehashHandler } from "facehash/next";
export const { GET } = toFacehashHandler();
export const { GET } = toFacehashHandler({
size: 200, // Default image size (default: 400)
variant: "solid", // "gradient" | "solid" (default: "gradient")
showInitial: false, // Show first letter (default: true)
colors: ["#ff6b6b", "#4ecdc4", "#45b7d1"], // Custom color palette
cacheControl: "public, max-age=86400", // Custom cache header
});
All options can be overridden via URL query parameters:
| Parameter | Type | Description |
|---|---|---|
name | string | Required. String to generate avatar from |
size | number | Image size in pixels (16-2000) |
variant | string | "gradient" or "solid" |
showInitial | boolean | "true" or "false" |
colors | string | Comma-separated hex colors (e.g., #ff0000,#00ff00) |
/api/avatar?name=john@example.com
/api/avatar?name=Alice&size=128
/api/avatar?name=Bob&variant=solid&showInitial=false
/api/avatar?name=Team&colors=%23ff6b6b,%234ecdc4,%2345b7d1
By default, responses include Cache-Control: public, max-age=31536000, immutable (1 year). Same name always generates the same image, so aggressive caching is safe.
// Main component
import { Facehash } from "facehash";
// Avatar compound components
import { Avatar, AvatarImage, AvatarFallback } from "facehash";
// Individual face components (for custom use)
import { RoundFace, CrossFace, LineFace, CurvedFace, FACES } from "facehash";
// Utilities
import { stringHash } from "facehash";
// Types
import type { FacehashProps, AvatarProps, AvatarFallbackProps, AvatarImageProps } from "facehash";
// Next.js route handler (facehash/next)
import { toFacehashHandler } from "facehash/next";
import type { FacehashHandlerOptions, FacehashHandler } from "facehash/next";
MIT — Built by Cossistant
FAQs
Deterministic avatar faces from any string. Lightweight, interactive, pure CSS. Works with any framework.
The npm package facehash receives a total of 11,844 weekly downloads. As such, facehash popularity was classified as popular.
We found that facehash demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.