Package development · Open source
Laralink
Work on a Composer package inside the Laravel app that uses it, then switch back to the Packagist release.
What it solves
To develop a package inside the app that uses it, you add a path repository to composer.json, require the package at @dev, and later undo both and restore the constraint you had.
Done by hand, a failed install leaves composer.json half edited and the old constraint is easy to lose.
laralink:dev links a package from a local folder or a Git repository through a symlinked Composer path repository, so every edit shows up in the app immediately. laralink:publish puts back the constraint the package had before and installs the released version.
- Link from a local folder (symlinked, or copied with --copy) or any Git URL and branch
- The path repository goes first in composer.json, so it wins over Packagist
- Checks the package's PHP and Laravel constraints against your app before changing anything
- Restores composer.json and removes the new link or clone if Composer cannot install the package
- laralink:publish restores the exact constraint the package had before it was linked
- Never deletes a symlinked source folder, or a clone with uncommitted changes unless you back it up or force it
Install
Requires PHP 8.3+ and Laravel 12 and 13.
composer require amjadiqbal/laralink --dev
Usage
php artisan laralink:dev --source=~/code/my-package # link a folder on your machine
php artisan laralink:dev vendor/package --branch=fix # or clone a branch from GitHub
php artisan laralink:list # what is linked, what is installed
php artisan laralink:publish vendor/package # back to the Packagist release
Setup
The service provider is discovered automatically and there is nothing to publish or configure. You need Composer 2 and Git on your PATH, and macOS or Linux for symlinks (on Windows use --copy). Add /packages to your app's .gitignore if you don't want linked packages committed.
Link a package: laralink:dev
Without arguments the command asks for a local path or a Git repository, and lists packages found next to your app (../*, ../*/*) and in ~/projects. A bare package name is cloned from https://github.com/vendor/package.git. --skip-version-check skips the PHP and Laravel check; --force points an existing symlink somewhere else and also skips the check.
php artisan laralink:dev --source=../my-package
php artisan laralink:dev vendor/package
php artisan laralink:dev [email protected]:acme/billing.git --branch=feature/invoices
What happens, in order
- 1 The package's composer.json is read (after cloning, for Git sources) and its name decides where it goes: ./packages/vendor/package.
- 2 Its php and Laravel constraints are checked against your app.
- 3 The folder is symlinked, copied or cloned into ./packages/vendor/package.
- 4 A path repository with "symlink": true is added first in your composer.json.
- 5 composer require vendor/package:@dev --with-all-dependencies runs, with --dev if the package was in require-dev.
See what is linked, and switch back
laralink:list shows each package's constraint, the version installed according to composer.lock, and a status: Linked, Local files, not linked, Linked, not required, or Remote. laralink:publish removes the path repository and installs the constraint the package had before it was linked, or the latest release. If no released version can be installed, composer.json is restored and the package stays linked.
php artisan laralink:list --filter=local
php artisan laralink:list --json
php artisan laralink:publish vendor/package --delete --backup
New in 2.0
1.x was never on Packagist. In 2.0 the three commands were rebuilt.
- --source, --branch, --copy, --skip-version-check and --force on laralink:dev.
- The PHP and Laravel compatibility check.
- laralink:list --json and --filter.
- laralink:publish --backup and --force, and restoring the previous constraint.
- Undoing its own changes when Composer fails.
- Requires PHP 8.3+ and Laravel 12 or 13.
Hire me
Need this built into your app, or something custom?
I wrote Laralink. I can wire it into your Laravel app, extend it for your case, or build the feature around it. Tell me what you need and you'll get a plan and a quote, free.
Support
Found a bug or want a feature? Open an issue on GitHub. For help adding it to your own project, use the quote form above.
More Laravel packages
All packages
Laravel Driver.js
Build Driver.js product tours in PHP and render them with one Blade component.
Laravel Sonner
Sonner toast notifications for Laravel, sent from PHP and shown without React.
Laravel Ninja Keys
A Cmd+K / Ctrl+K command palette for Laravel, with the actions defined in PHP.
Laravel SweetAlert2
SweetAlert2 popups, toasts and confirm dialogs from Laravel controllers, Livewire and Alpine.
Laravel Grid.js
Turn any Eloquent query into a searchable, sortable, paginated Grid.js data table with one fluent PHP call.
Refresher
A drop-in replacement for Laravel's RefreshDatabase that restores a cached snapshot of your test database instead of running migrate:fresh.
Kiln
Artisan commands and an optional signed HTTP route to clear, warm and inspect OPcache when you deploy.
Laravel Media Viewer
Show private PDFs, video and audio from any Laravel disk without making the files public.
Laravel Swiper
Swiper sliders, carousels and image galleries for Laravel as Blade components.
Laravel MySQL Advisor
Read-only health checks for the MySQL or MariaDB database behind your Laravel app, with the SQL and the Laravel migration to fix a problem wherever a fix applies.
Laravel Webhook Console
A dashboard and replay tool for the webhooks spatie/laravel-webhook-client stores in your Laravel app.