dicebear/styles
Official collection of avatar styles for DiceBear, the open-source avatar library. Browse dozens of customizable SVG and PNG styles—adventurer, avataaars, bottts, and more—all exposed through a consistent API for generating unique user avatars.
The first thing to internalise: dicebear/styles is not a Composer package. It is the upstream source of DiceBear's official style definitions (JSON/SVG-part data consumed by @dicebear/core), published through npm as the aggregate @dicebear/collection and/or per-style packages (@dicebear/initials, @dicebear/avataaars, @dicebear/bottts, …). If you run composer require dicebear/styles you will get nothing useful. Confirm by inspecting the repo root for a package.json rather than a composer.json, and look first at how styles are laid out (each style has a definition file plus components/, colors, and a license).
Decide your integration path before touching code, because it dictates everything else:
https://api.dicebear.com/<version>/<style>/svg from a Laravel controller or via Http:: and cache the result.@dicebear/core and the style/collection package in your Vite bundle and render client-side.storage/app/avatars so PHP never needs Node at request time.A good first use case is the classic: a deterministic default avatar for every user, seeded by email, with a fallback to initials.
// app/Services/AvatarService.php
use Illuminate\Support\Facades\Http;
public function url(string $seed, string $style = 'initials'): string
{
return 'https://api.dicebear.com/9.x/'.$style.'/svg?seed='.urlencode($seed);
}
In a Blade/Inertia view, seed from something stable — never now() — so the avatar doesn't churn on every render:
$seed = Str::of($user->email)->lower()->trim()->toString();
If you go the front-end route, the minimal install is npm i @dicebear/core @dicebear/collection, then createAvatar(initials, { seed }) in a Vue/React component. Keep the seed computed server-side and passed as a prop so PHP and JS agree on identity.
1. Server-side proxy + cache (the Laravel-native default). Wrap the HTTP API in a service with a cache key derived from style + version + seed + options, and store the SVG body, not just the URL:
$key = 'avatar:'.sha1("{$style}:{$version}:{$seed}:".json_encode($options));
return Cache::remember($key, now()->addDay(), function () use ($style, $seed, $options) {
$res = Http::timeout(5)->retry(2, 200)
->get("https://api.dicebear.com/{$version}/{$style}/svg", ['seed' => $seed] + $options);
return $res->successful() ? $res->body() : null;
});
Serve it from a route (Route::get('/avatars/{seed}', ...)) with a long Cache-Control, and let the browser/CDN do the heavy lifting.
2. Persisted avatar metadata on the model.
Don't recompute style/options ad hoc. Add columns (avatar_style, avatar_seed, avatar_options JSON) and generate a URL via an accessor. This makes style changes an explicit migration/backfill decision instead of a silent visual break for every user on deploy.
3. Pre-generation via Artisan + Node.
For deterministic assets (marketing pages, emails, PDFs), generate SVGs once in a queue job or build step. A Node script writes files; an Artisan command shells out or calls the API and copies results into storage/app/public/avatars/{id}.svg. This keeps runtime PHP free of Node and avoids per-request network calls. Pair it with php artisan storage:link.
4. Front-end component with SSR-safe rendering.
In an Inertia app, generate the SVG string with @dicebear/core and either insert via v-html/dangerouslySetInnerHTML or build a data:image/svg+xml;base64,... URI. Prefer the <img src="data:..."> form — it sidesteps script-injection concerns entirely and lets the browser cache the image.
5. Option-driven variation.
Lean on per-style options (backgroundColor, radius, flip, rotate, scale, palette arrays) passed as query params or to createAvatar. Define a whitelist of allowed options in config so user-supplied style/option input can't hit arbitrary keys, and validate with a FormRequest.
6. Consistent identity across surfaces.
Centralise seeding (email hash, or crc32(user_id)) in one helper. If avatar and avatar-in-email disagree, it's almost always because one surface used the raw email and the other lowercased it, or the API version differs.
NOASSERTION, and each individual style carries its own terms (CC0, CC BY 4.0, MIT, etc.). Some require attribution. Before shipping a style in a commercial product, open that style's license file and record the attribution requirements in your project's THIRD_PARTY_NOTICES. Don't assume "official DiceBear = free for anything."composer require this is wrong or referring to a third-party PHP wrapper. Treat the JS package as build-time tooling and the HTTP API as the runtime contract./9.x/). Pin the version in config, and if visual stability matters for existing users, hash the version into your cache key and store rendered SVGs rather than regenerating on every request.trim() difference between two call sites produces "two avatars for one user."data: URIs or stored files. If you proxy the API, consider passing through a Content-Security-Policy and serving as image/svg+xml.backgroundColor or palette means users see stale avatars after changing settings — a classic "why didn't it update?" bug.size param, strip unnecessary attributes, or gzip. Serving via a route with Cache-Control: public, max-age=31536000, immutable is better than re-rendering per page view.How can I help you explore Laravel packages today?