Likes: One like per pair, guaranteed by the database
Add CanLike to the model that likes and HasLikes to the model that is liked, run one migration, and write $user->like($post). A unique index keeps each pair to one row, even when two requests arrive at once.
Likes that stay correct
A small API on top of native Eloquent relations.
Results That Say What Changed
like() and unlike() return true only when they changed the table, so a repeated click is easy to tell apart.
Unique by the Database
A unique index on the four columns keeps each liker and likeable pair to one row, under concurrent requests too.
Any Model Likes Any Model
Users, teams or bots like posts, comments, products or each other. One model can use CanLike and HasLikes together.
Native Counts and Eager Loading
withCount('likes'), with('likes.liker') and whereLikedBy($user) run in SQL, without loading every like.
Integer, UUID and ULID Keys
Ids are stored as strings, so models with different key types share one table, with morph map aliases respected.
Clean Deletes
Deleting a model deletes its likes; a soft delete keeps them, so a restored model keeps its likes.
A quick look
A user likes a post, and the post page shows its count.
1use App\Models\Post; 2 3Route::post('posts/{post}/like', function (Post $post) { 4 $created = request()->user()->like($post); 5 6 return response()->json([ 7 'created' => $created, // false when it was already liked 8 'likes' => $post->likes()->count(), 9 ]);10})->middleware('auth');11 12Route::get('posts', function () {13 return Post::withCount('likes')->latest()->paginate();14});Likes Questions
Quick answers about installing and using Likes.
What is Likes?
Let any Eloquent model like any other: like, unlike and toggle with results that say what changed, a unique index that keeps each pair to one row, and native relations for counts and eager loading. It's a free, open-source Laravel package by Pharaonic.
How do I install Likes?
Run composer require pharaonic/laravel-likes in your project's root directory, then php artisan migrate.
What does Likes require?
The latest release requires PHP 8.3+ and Laravel 13.
Does the liker have to be a user?
No. Any Eloquent model with the CanLike trait can like, and any model can be liked. Nothing in the package reads the authenticated user.
What happens when the same user likes twice at the same moment?
One request creates the like and returns true; the other finds the unique index in its way and returns false. The table never holds two rows for the pair.
Can I use it with UUID or ULID models?
Yes. Ids are stored as strings of up to 64 characters, so integer, UUID and ULID models can like each other in the same table.
Is Likes free to use?
Yes. Likes is open source under the MIT license, so you can use it in personal and commercial projects.
Where can I find the Likes documentation?
Read the Likes documentation for setup, configuration, and usage examples.
How do I report a bug or contribute to Likes?
Open an issue or a pull request on GitHub, or ask in the Pharaonic Discord.
Ready to dig in?
Read the full documentation for installation, configuration, liking and unliking, relations, counts and filters, morph maps and key types, events, deletes and soft deletes, concurrency, the API reference, examples, and troubleshooting.