Model or dataset
multicaret/laravel-acquaintances avatar
multicaret/laravel-acquaintances

laravel-acquaintances: social features as Eloquent traits

This package gives Eloquent models the ability to manage friendships (with groups), followships along with Likes, favorites..etc.

853 stars69 forksPHPMIT

At a glance

What is it?
laravel-acquaintances gives Eloquent models friendships with groups, verifications, and a set of interactions including follow, like, favourite, report, subscribe, vote and view, plus multi-type ratings. The 4.0 line adds UUID and ULID morph support, a caching layer and counter macros, and it is still a beta, so most production installs are on 3.7.
Who is it for?
Adopt laravel-acquaintances if your Laravel application needs social graph behaviour and you would rather not own the tables, the pending request states and the counter columns yourself, because the package covers friendships, verifications and a wide set of interactions behind a small trait-based API that works on your existing models.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A package for the social parts of an application

laravel-acquaintances gives Eloquent models the ability to manage friendships with groups, followships, and along with them likes, favourites and similar. The README puts it more precisely as clean, modular social features for Eloquent models, split into four families: Friendships, Verifications, Interactions covering Follow, Like, Favorite, Report, Subscribe, Vote and View, and multi-type Ratings.

That last split is what makes the package worth reading rather than just using. A social application usually needs a handful of many-to-many relations, and each of them has a slightly different shape. A follow is one-sided and needs no approval. A friendship is two-sided and needs a request and an acceptance. A verification is a two-sided claim that one user asserts about another, with an optional message and an acceptance step. A like or a favourite is a one-sided flag. A vote is a one-sided flag that carries a value. A rating is a value with a type, which is why the ratings are described as multi-type.

The package covers all of them behind one vocabulary, which is the part that saves the most work. The relations themselves are ordinary database tables with a polymorphic twist, so nothing about it is exotic. The value is in having the states, the pending requests and the counters already worked out.

The requirements are PHP 8.1 or newer and Illuminate components from 9.0 through 13.0, which is Laravel 9 to 13. The licence is MIT, the primary language is PHP, the default branch is master, and the last push was on 2026-04-09. The package is on Packagist as multicaret/laravel-acquaintances, and the README links a write-up on Laravel News that describes the package in more detail than the README does.

The TL;DR block is the API in twelve lines

The README's quick example is the clearest statement of the design, and it is short enough to take in at a glance.

php
$user1 = User::find(1);
$user2 = User::find(2);

// Friendships
$user1->befriend($user2);
$user2->acceptFriendRequest($user1);

// The messy breakup :(
$user2->unfriend($user1);

// Verifications (message is optional)
$user1->verify($user2, "Worked together on several Laravel projects.");
$user2->acceptVerificationRequest($user1);

if ($user1->isVerifiedWith($user2)) {
    echo "Verified!";
}

The vocabulary is verbs on the model, not calls on a service or a manager class. You ask a user to befriend another user, and the other user accepts the request, and either side can end the friendship. The comment about the messy breakup is the author's, and it points at something real: a friendship is a relation with a history of states, and unfriending is not the same operation as never having been friends.

Verifications work the same way but carry an optional message, and there is a predicate, isVerifiedWith, to ask about the result. That is a small API surface, and the readability comes from the model methods reading like sentences, which is the entire argument for trait-based packages in a framework where everything is a class.

What the example does not show is the parts that are less tidy, which is what the rest of the documentation is for.

Traits come in pairs, and the pairing is the point

The third quickstart step is to add traits to your models, and the list shows the shape of the whole package:

php
class User extends Model {
    use Friendable, Verifiable;
    use CanFollow, CanBeFollowed;
    use CanLike, CanBeLiked;
    use CanRate, CanBeRated;
}

Every relation comes in two halves, and the halves are not symmetric in name. The first trait is the active side, the one that acts, and the second is the passive side, the one that is acted upon. A model that can follow uses CanFollow, and a model that can be followed uses CanBeFollowed, and a model that is both, which is the usual case for a social graph, uses both. The same pattern repeats for likes and for ratings.

The friendship and verification traits are different in kind, because those relations are two-sided by definition, so Friendable and Verifiable each cover both directions and there is no separate passive trait.

So the cost of adoption is one use statement per relation you want on a model, and the benefit is that a model gains the verbs, the predicates and the relation queries for that relation, with the tables and the pending state handled by the package's migrations. A user model in a typical application ends up with six of the eight traits, and a subject that can only be liked gets one.

The features config decides which tables you get

The most consequential configuration decision in the package is the one that decides what lands in your database.

If you only need interactions, which are Follow, Like, Favorite, Subscribe, Vote, View, Report and Rate, and you do not need Friendships or Verifications, you disable them in config/acquaintances.php:

php
'features' => [
    'interactions' => true,
    'friendships' => false,
    'verifications' => false,
],

This prevents the friendship and verification migrations from being loaded or published, which the README says keeps your database lean. It is a genuinely useful option, because a package that installs every table by default is a package that leaves a set of empty tables behind in every project that only wanted a like button.

The granularity goes one level further, because migrations can be published per feature with tags:

bash
php artisan vendor:publish --tag=acquaintances-migrations-interactions

with matching tags for friendships and verifications. The full install path is the usual three steps, composer require multicaret/laravel-acquaintances, then an optional vendor:publish with the AcquaintancesServiceProvider, then php artisan migrate.

The other configuration worth knowing is about your user model. If your User model lives in a non-standard namespace, you set user_model_class_name in the config file, for example to a class in App\Models\Core\User. When it is null, which is the default, the package resolves the user model from model_namespace plus models.user, which is how it arrives at App\Models\User. That is a small detail, but it is the kind of thing that breaks silently in a project with a layered namespace, and it is why the option is there.

What version 4 actually adds

The README has a section for what is new in v4, and it reads like a list of things that were missing in 3.x rather than a list of new ideas.

UUID and ULID morph support is configurable per table through morphs, uuidMorphs or ulidMorphs, which matters as soon as a project uses UUID primary keys, because the default morph columns are integer identifiers. A caching layer provides an in-memory request cache plus an optional persistent cache for interaction checks with automatic invalidation, which is the answer to a real problem: a check like isLiked runs on every render of every list, and a package that can cache that within a request and optionally across requests removes a large number of queries. A withAcquaintanceCounts() macro eager-loads interaction counts in a single query, and a HasAcquaintanceCounters trait auto-increments and decrements counter columns on your model's table, which is the difference between counting on read and counting on write.

There is also an AcquaintancesCleanupJob for queued mass deletion of acquaintance data for deleted models, database indexes, composite and unique, on all the tables for faster lookups, and automatic morph map registration for all package models. Strict return types are applied on all traits and models, and DB transactions now wrap blockFriend() and blockVerification().

Interactions-only mode and the granular publish tags are part of the same release, which is why the v4 line is a coherent step rather than a collection of additions.

The upgrade path is documented separately, in docs/12.upgrade.md, and the changelog has the full list, which is the arrangement you want when a release changes the database schema.

Twelve documentation files, and a README that stays short

The README states its own policy: to keep this README concise, the full documentation lives under docs/. The files are numbered, which tells you the intended reading order: an overview at docs/1.overview.md, then installation, configuration, friendships, verifications, interactions, ratings, migrations, events, testing, an FAQ, and finally the upgrade notes at docs/12.upgrade.md.

That structure is worth a moment's thought, because it is a deliberate choice about where a package's documentation should live. A README that grows to five thousand words is a README nobody reads, and the file list here also shows what the package considers worth its own chapter. Events have their own document, which tells you the package emits application events for the things that happened, and testing has one, which tells you it is written to be tested.

The repository layout is the conventional Laravel package: a src/ directory for the code, config/ for the configuration file, database/ for the migrations, tests/ for the test suite, a phpunit.xml, a composer.json, a CHANGELOG.md, a CONTRIBUTING.md and a LICENSE, plus docs/ for the documentation above.

The homepage in the repository metadata points at the Laravel News article, which is a longer introduction to the package for people deciding whether to look at the source at all, and it is a reasonable first stop for an engineer who has not yet decided whether they need a social layer at all.

The compatibility table tells you which line to install

There is a small table at the end of the README that answers the only question that really matters for an install:

| Version | PHP | Laravel | | v4 | >= 8.1 | 9, 10, 11, 12, 13 | | v3.x | >= 8.0 | 9, 10, 11, 12 |

The v4 line drops PHP 8.0 and adds Laravel 13, and the v3.x line is the one that still runs on PHP 8.0 and Laravel 9 to 12.

What the release list adds is the caveat. The newest release is v4.0.0-beta.1, published on 2026-04-09, which is the same day as the last push to the repository. Before that came v3.7.3 in August 2025 and v3.7.2 in March 2025.

So the 4.0 line is a beta, and the 3.7 line is the one that has been stable for a while. For a project that is not upgrading the framework version and does not need UUID morphes or the counters, the 3.7 line is the safer choice, and for a project on Laravel 13 the 4.0 beta is the only option and the beta label is the price.

One detail from the release list deserves attention: the beta was published in April 2026 and the repository has not been touched since. That is a project that reached a milestone, cut the beta, and paused, which is a reasonable thing for a package maintainer to do and a reasonable thing for you to plan around.

Editorial conclusion

Adopt laravel-acquaintances if your Laravel application needs social graph behaviour and you would rather not own the tables, the pending request states and the counter columns yourself, because the package covers friendships, verifications and a wide set of interactions behind a small trait-based API that works on your existing models. Do not start a new project on 4.0 yet, because the newest release is v4.0.0-beta.1 and the compatibility table shows 3.7 as the line that supports the widest set of Laravel versions with the older PHP floor. Before you install, read the interactions-only mode, because it decides which migrations are published and therefore what your database ends up containing, and check the upgrade notes in docs/12.upgrade.md if you are moving from 3.x.

Frequently asked questions

How do I install laravel-acquaintances?

Run composer require multicaret/laravel-acquaintances, optionally publish the configuration with php artisan vendor:publish --provider="Multicaret\Acquaintances\AcquaintancesServiceProvider", and then php artisan migrate. The package requires PHP 8.1 or newer and Illuminate components 9 through 13.

Can I use laravel-acquaintances without the friendship tables?

Yes. Set 'features' in config/acquaintances.php with 'interactions' => true and 'friendships' and 'verifications' set to false, which prevents those migrations from being loaded or published. Migrations can also be published one feature at a time with the acquaintance-migrations-interactions, -friendships and -verifications tags.

Which traits do I add to my User model?

Friendable and Verifiable for the two-sided relations, and a pair for each one-sided one, CanFollow with CanBeFollowed, CanLike with CanBeLiked, and CanRate with CanBeRated. A model that both acts and is acted upon uses both halves of a pair, and a model that is only ever the target of a relation needs only the passive trait.

Is laravel-acquaintances version 4 ready to use?

The newest release is v4.0.0-beta.1, a beta, and the compatibility table shows v4 requiring PHP 8.1 or newer with Laravel 9 to 13, while the v3.x line requires PHP 8.0 with Laravel 9 to 12. The v4 additions include UUID and ULID morph support, a caching layer, counter macros and a cleanup job, and the migration steps are documented in docs/12.upgrade.md.

Official sources

  1. License: MIT
  2. multicaret/laravel-acquaintances on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/multicaret-laravel-acquaintances.svg)](https://hysenlabs.com/projects/multicaret-laravel-acquaintances)

Was this useful?