Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Gravatar Laravel Package

tomshaw/laravel-gravatar

Gravatar avatars, profiles, and QR codes for Laravel. Zero config to start, configurable when you need it, with a Blade directive and component for rendering, a facade and fluent builder for URLs, plus model support, profiles, QR codes, and hashing.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a thin, stateless adapter over Gravatar's public HTTP endpoints — one service provider, one facade, one Blade component/directive, one opt-in Eloquent concern (HasGravatar). No migrations, no queues, no global scopes, no forced base classes. That is the right shape: it can be dropped into an existing Laravel app without touching the domain model. Two details signal real Laravel fluency rather than a wrapper thrown together: the trait deliberately prefixes every method (gravatarUrl(), not gravatar()) to avoid Eloquent's attribute-resolution LogicException, and the component distinguishes default (rendered by Gravatar) from fallback (shown when the request fails outright). Both are the kind of thing you usually only learn from production incidents.

Where the value actually is. Roughly 80% of the surface — src() and the fluent builder — is a SHA256 of a lowercased email plus a query string. Any mid-level developer reproduces that in an afternoon. The durable value is the periphery: the component's 2x srcset and onerror fallback, the cached profile client (misses cached too), QR generation, and Gravatar::fake() for deterministic tests. Judge the package on those, not the URL builder.

Integration feasibility. Composer-only, auto-discovered, zero config required, config and views publishable. The blocker is the hard platform floor: PHP 8.5 and Laravel 13. That excludes essentially every maintained estate today. Earlier tags (0.2.x) supported Laravel 12, so the version matrix — not the package — determines feasibility. Confirm the tag that matches your runtime before committing.

Technical risk.

  • Adoption signal vs. quality signal. 1 star and 0 dependents is a popularity proxy, not a quality verdict. The repo has Pest tests, PHPStan, Pint, CI, a CHANGELOG, release tags, and a documented parameter reference — well above the norm for a 1-star package. Read it as pre-release, not defective.
  • Bus factor 1. Single maintainer, no commercial support, no visible SECURITY.md. Abandonment is the dominant risk.
  • Platform treadmill. Requiring PHP 8.5/Laravel 13 means your framework upgrade cadence is now the package's cadence.
  • Render-time validation. Out-of-range parameters throw InvalidArgumentException. Failing loudly beats a dead URL in dev — but a bad value in config/gravatar.php becomes a page-wide 500 in production.
  • Third-party egress and privacy. Email hashes leave your infrastructure. SHA256 is the correct call and matches Gravatar's own guidance, but an unsalted hash of a low-entropy identifier is pseudonymization, not anonymization. This belongs in your subprocessor list.
  • MD5 footgun. The legacy path is one global config flip away from silently downgrading every URL.

Key questions for the maintainer: Is the PHP 8.5 floor intentional (narrower CI matrix) or incidental? Will features be backported to the Laravel 12 line? What's the support window for Laravel 14? Do has()/profile() expose timeouts, retries, and 429s, or swallow them? Is there a security policy? Any intent to support alternative providers (Libravatar, self-hosted proxies) for on-prem or restricted-network deployments?

Integration Approach

Stack fit. Works in any Laravel 13 deployment: Blade/Livewire use the component or directive directly; Inertia and SPA front-ends call the facade server-side and pass URLs down as props. Compatible with any cache store, which matters for the profile client in multi-node setups.

Migration path. Two common origins:

  • Hand-rolled helpers (md5(strtolower(trim($email))) in a User::avatar() accessor). Swap to $user->gravatarUrl(); the trait's configurable gravatarEmailColumn() plus per-model override handles non-standard columns.
  • Prior packages (thomaswelton/laravel-gravatar, creativeorange/gravatar). Map Gravatar::get() → Gravatar::src() / Gravatar::for()->url(). Keep hash: 'md5' during cutover so existing URLs, CDN cache keys, and any avatar_url columns denormalized in the database still resolve, then flip to SHA256 as a separate, independently revertible change.

Compatibility checks before install: PHP/Laravel floors against your runtime; Blade component namespace collision on <x-gravatar>; model method-name collisions with any existing HasGravatar or avatar accessor; cache prefix isolation if you reuse a shared Redis; egress allowlists for secure.gravatar.com and the QR endpoint (Gravatar is blocked on some corporate and national networks).

Sequencing.

  1. ADR and privacy/subprocessor review — decide whether email hashes may leave the perimeter at all.
  2. Install, publish config, pin an exact version tied to your framework version.
  3. Blade-only rollout on one low-traffic surface, with fallback pointing at a local asset from day one.
  4. Internal facade adoption behind a thin Avatar service of your own (see mitigation below).
  5. Optional: profile enrichment with cache and API key — only where a feature genuinely consumes fields like jobTitle or location.
  6. Optional: QR codes — only if a profile-sharing feature exists.
  7. Wire Gravatar::fake() into the test suite so CI never depends on Gravatar's availability.

Every step is independently revertible because URL building is stateless and the profile path is additive.

Operational Impact

Maintenance. Small surface, MIT, trivially forkable. Assign a named owner and a dependency-watch policy, knowing the platform floor couples package upgrades to framework upgrades. Budget one to two days a year, plus a fork contingency. The highest-leverage mitigation is architectural, not procedural: wrap the facade in your own two-method Avatar service and call that everywhere. It costs an hour and makes the package replaceable by a 50-line internal class if the repo goes dark.

Support. Community-only, no SLA, GitHub issues. Gravatar itself is Automattic-run with no SLA either — you are inheriting two layers of unsupported dependency. Pin exact versions and vendor the source if procurement requires provenance.

Scaling. URL construction is O(1), free, and adds no load. The profile client is the only scaling consideration: one outbound HTTP call per uncached email at a 3600s default TTL. Caching misses is the smart design choice here — the majority of users have no Gravatar account, and without negative caching every page load for those users is a wasted round trip. Real risks are cold-cache stampede across pods after a deploy (warm the cache or add jitter/locking) and template-level misuse — a profile() call inside a Blade partial over a user list turns one page into N synchronous outbound requests. Prefetch asynchronously or restrict to detail views.

Failure modes.

  • Gravatar unreachable (outage, DNS, firewall, regional block) → broken avatar images. This is exactly what fallback + onerror solves, and exactly what default does not solve, since default requires Gravatar to be reachable. Train the team on that distinction — it is the single most consequential piece of tribal knowledge in this package.
  • Config-driven exception → whole-template 500 from one bad enum value. Add a config-assertion test in CI.
  • Silent field withholding without an API key (timezone, languages, links, contact info) → features built on those fields degrade quietly rather than failing. Either set a key or don't build on them.
  • Profile staleness — a user updates their Gravatar and your cache holds the old payload for up to the TTL.
  • MD5 leakage — if the global hash config is ever flipped for legacy compatibility and never flipped back.

Ramp-up. A competent Laravel developer is productive in under an hour given the zero-config default and the README's parameter-reference table and testing section — documentation quality is genuinely above average here. The training burden is not the API; it's four decision points: default vs fallback, SHA256 vs MD5, never call HTTP methods from a view, and validate config at boot rather than at render.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console