Deterministic avatars
from any string
A name, an email, an ID — Facehash turns it into the same friendly SVG face every time. No GD, no Imagick, no external services.
Try it with your own name
Rendered in your browser by a port of the same renderer the package ships.
Every knob, pre-rendered
All of the SVG below was generated at build time by the PHP renderer.
Format
square, squircle or circle
Variant
Radial highlight or flat fill
Initial
First letter of the name, below the eyes
Blink
CSS animation embedded in the SVG
Size
Geometry scales with the pixel size
Palette
Any list of colors you like
4 face types × 5 colors × 9 tilts
180 distinct faces from the default palette — before you add colors of your own.
Installation
Requires PHP 8.2+ and Laravel 11, 12 or 13.
composer require saade/facehash The service provider and the Facehash facade are auto-discovered — there is nothing to register.
Quick start
use Saade\Facehash\Facades\Facehash;
// Generate an SVG string
$svg = Facehash::name('Saade')->toSvg();
// Embed as a data URI in an <img> tag
$uri = Facehash::name('Saade')->toUri();
Builder API
Every method returns a new instance, so you can keep a configured builder around and branch off it without side effects.
name(string $name)
Required. The input string. The same string always produces the same face.
Facehash::name('alice@example.com')->toSvg();
size(int $pixels)
Avatar dimensions in pixels. Default: 40.
Facehash::name('Saade')->size(128)->toSvg();
variant(string $variant)
Background style — 'gradient' or 'solid'. Default: 'gradient'.
Facehash::name('Saade')->variant('solid')->toSvg();
format(string $format)
Avatar shape — 'square', 'squircle' or 'circle'. Default: 'circle'.
Facehash::name('Saade')->format('squircle')->toSvg();
blink(bool $enable = true)
Adds a CSS blink animation to the eyes, inlined in the SVG. Default: false.
Facehash::name('Saade')->blink()->toSvg();
initial(bool $show = true)
Show the first letter of the name below the eyes. Default: true.
Facehash::name('Saade')->initial(false)->toSvg();
colors(array $colors)
Override the palette. Each avatar deterministically picks one color from the list.
Facehash::name('Saade')->colors(['#6366f1', '#8b5cf6', '#a78bfa'])->toSvg();
Output methods
| Method | Returns |
|---|---|
toSvg() | Raw SVG string |
toBase64() | Base64-encoded SVG |
toUri() | Data URI (data:image/svg+xml;base64,…) |
Blade usage
{{-- Inline SVG --}}
{!! Facehash::name($user->name)->size(48)->toSvg() !!}
{{-- As <img> src --}}
<img src="{{ Facehash::name($user->name)->size(48)->toUri() }}" alt="{{ $user->name }}">
{{-- Via the route --}}
<img src="{{ route('facehash', ['name' => $user->name, 'size' => 48]) }}" alt="{{ $user->name }}">
HTTP route
The package ships an optional GET endpoint that returns an image/svg+xml response with
long-lived cache headers. It is disabled by default.
// config/facehash.php
'route' => [
'enabled' => true,
], GET /facehash?name=Saade
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
name | string | required | Input string |
size | int | 40 | Size in pixels (16–1024) |
variant | string | gradient | gradient or solid |
format | string | circle | circle, square, squircle |
initial | bool | true | Show initial letter |
blink | bool | false | Enable blink animation |
colors[] | string[] | — | Custom hex palette |
<img src="/facehash?name=Saade" alt="Avatar">
<img src="/facehash?name=Saade&size=128&variant=solid" alt="Avatar">
<img src="/facehash?name=Saade&colors[]=%236366f1&colors[]=%238b5cf6" alt="Avatar">
Configuration
php artisan vendor:publish --tag=facehash-config <?php
return [
'defaults' => [
'size' => 40,
'variant' => 'gradient',
'format' => 'circle',
'initial' => true,
'blink' => false,
],
'colors' => ['#ec4899', '#f59e0b', '#3b82f6', '#f97316', '#10b981'],
'route' => [
'enabled' => false,
'prefix' => 'facehash',
'middleware' => ['web'],
'cache_control' => 'public, max-age=31536000, immutable',
],
]; - defaults — starting values for the builder; any method call overrides them per instance.
- colors — the palette each avatar picks from. The shipped default uses Tailwind's 500-weight colors.
- route.enabled — register the HTTP endpoint. Off by default.
- route.cache_control — the default caches for a year as immutable, which is safe because the same input always produces the same bytes.
How it works
- The input string is hashed to a deterministic 32-bit integer.
- The hash picks a face type, a color from the palette, and one of nine tilts that offset the face for a subtle 3D look.
- The renderer composites the clip path, background, gradient overlay, eye paths and the initial letter into a single SVG.
- The same string always produces the exact same SVG — across requests, servers and deploys.
Face types
Credits
A PHP/Laravel port of facehash by Cossistant, which provides the face paths, hash algorithm and rendering logic this package reproduces. Released under the MIT license.