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

Me Like Laravel Package

mvo/me-like

mvo/me-like is a lightweight Laravel package that adds like and unlike support to Eloquent models. Use a simple trait to let users like posts, comments, or any model, with polymorphic relationships and easy queries for counts and liked items.

View on GitHub
Deep Wiki
Context7

Getting Started

At v0.1.1 this is pre-1.0 software; treat the first hour as due diligence, not setup.

  1. Read the source before the README. At 0.x the docs are usually a stub. Open composer.json first and check the constraints (php, illuminate/*). If it pins ^10.0 and you're on Laravel 11, stop here.
  2. Install on a branch, never on main.
    composer require vendor/package:0.1.1
    
    Pin the exact version. Do not write ^0.1 — you want to opt into each 0.x bump deliberately.
  3. Confirm auto-discovery worked. Laravel registers the service provider via extra.laravel.providers. Verify with:
    php artisan about          # providers section
    php artisan package:discover --ansi
    
    If the package ships a facade and a config file, publish only the config:
    php artisan vendor:publish --tag=package-config
    
  4. Skim the service provider. src/*ServiceProvider.php is the real API surface: what's bound as a singleton, what's merged from config, what events it fires, whether it registers routes, migrations, or commands. That file tells you more than any docs.
  5. First use case. Pick one non-critical path — a single queued job or an artisan command — and call the package there behind a config flag. Do not wire it into a request lifecycle you can't roll back.

Implementation Patterns

Wrap it in your own adapter. The single highest-value pattern for a 0.x dependency:

// app/Services/Contracts/WidgetClient.php
interface WidgetClient { public function fetch(string $id): Widget; }

// app/Services/PackageWidgetClient.php
final class PackageWidgetClient implements WidgetClient
{
    public function __construct(private \Vendor\Package\Client $client) {}

    public function fetch(string $id): Widget
    {
        return Widget::fromPackage($this->client->get($id));
    }
}

Bind it in AppServiceProvider. Every call site types against your interface. When v0.2 renames get() to find(), you change one file. It also gives you a seam for ->fake() and for swapping the package out later.

Keep facades at the edges. Package facades resolve through the container and are convenient in controllers and commands, but injecting the facade into domain code makes it untestable without booting the framework. Inject the contract; use the facade only in glue code.

Config is the integration point. Read every key the package merges in mergeConfigFrom() and surface the ones you care about as env vars in your config/services.php or a dedicated file. Never edit vendor/ config and never rely on the package's defaults in production — they're optimized for "works locally."

Queue it if it touches the network. Anything doing HTTP, filesystem, or third-party API calls belongs in a job with $tries, $backoff, and $timeout set explicitly. At 0.1.x, assume no retry logic is built in until you've read the code and confirmed otherwise.

Testing. Check for a shipped fake (Package::fake(), Http::fake() usage in src/ or tests/). If there isn't one, bind a mock of your adapter interface — another reason to have the adapter. For integration coverage, use RefreshDatabase if the package publishes migrations, and assert against the real config rather than mocking the container.

Rollout. Feature-flag the call site, deploy to one worker or one queue, watch it for a day. Log the package version at boot so your logs tell you which build produced a failure.

Gotchas and Tips

  • 0.x semver is not semver. Anything can break in a patch release until 1.0. Commit composer.lock, pin exactly, and read the diff before bumping. Budget an hour per upgrade.
  • Published config is frozen. vendor:publish copies once; new keys added in later versions silently don't appear in your file. After every upgrade, re-publish to a temp path and diff against yours:
    php artisan vendor:publish --tag=package-config --force
    git diff config/package.php
    
  • Stale caches after install. php artisan config:clear && php artisan package:discover fixes the majority of "class not found" and "config is null" reports. Under Octane, singletons bound in the provider survive between requests — restart workers after a config change or you'll debug a ghost.
  • Migrations may not be publishable. Check loadMigrationsFrom() vs. a publish tag. If they're loaded from vendor/, you can't edit them and a rollback may drop tables you now depend on. Run php artisan migrate --pretend first.
  • Facade static calls hide the dependency. Package::doThing() in a model observer is invisible to static analysis and impossible to fake without Facade::swap. If you must, swap in tests explicitly.
  • The tests are the spec. With thin docs, tests/ in the vendor directory (or on GitHub) is the only reliable description of edge-case behavior — nullability, empty collections, error paths. Read it before writing your own.
  • Watch for missing timeouts and unbounded retries. External-call packages at this stage frequently ship with Guzzle defaults. Set timeout in config if exposed; otherwise wrap the call in your adapter with your own Http::timeout().
  • Extension points, in order of stability: container bindings (rebind after the package's provider registers, i.e. in your own register() — check ordering), events the package dispatches (listen, don't subclass), then macros. Avoid extending concrete package classes; those are the first thing to change shape.
  • Debugging. app()->make(\Vendor\Package\Client::class) in php artisan tinker shows you the resolved instance and its constructor deps instantly. Telescope will show you whether the package's outbound calls are actually firing when you expect. If something "does nothing," it's usually a silently-swallowed exception in the package — grep the source for catch.
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.
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
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource