NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Package Toolkit for Laravel

Migrating a package

Moving an existing package onto the toolkit is mechanical — four steps.

1. Extend PackageServiceProvider

Extend PackageServiceProvider instead of a hand-wired provider and move the mergeConfigFrom / loadX / publishes / commands tail into configurePackage(). A typical hand-wired provider:

use Illuminate\Support\ServiceProvider;

final class CommentsServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->mergeConfigFrom(__DIR__.'/../config/comments.php', 'comments');
    }

    public function boot(): void
    {
        $this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'comments');

        if ($this->app->runningInConsole()) {
            $this->publishes([
                __DIR__.'/../config/comments.php' => config_path('comments.php'),
            ], 'comments-config');

            $this->publishes([
                __DIR__.'/../resources/lang' => $this->app->langPath('vendor/comments'),
            ], 'comments-translations');

            $this->commands([PruneCommentsCommand::class]);
        }
    }
}

becomes a single declaration with the same publish tags:

use RoundlyConsulting\PackageToolkit\Package;
use RoundlyConsulting\PackageToolkit\PackageServiceProvider;

final class CommentsServiceProvider extends PackageServiceProvider
{
    public function configurePackage(Package $package): void
    {
        $package
            ->name('comments')
            ->hasConfigFile()                               // same comments-config tag
            ->hasTranslations()                             // same comments-translations tag
            ->hasCommands([PruneCommentsCommand::class]);
    }
}

If the package used to auto-load its migrations, note that the toolkit publishes them instead: tell hosts to publish and migrate, and load the migrations explicitly in the package’s own TestCase.

2. Use KeyType, the macros and DatabaseDriver

Delete the package’s local *KeyType enum and driver magic strings; use KeyType with the schema macros, and DatabaseDriver:

// Before — driver magic strings and a hard-coded key column
if (DB::connection()->getDriverName() === 'pgsql') {
    // …
}
$table->unsignedBigInteger('author_id')->index();

// After — DatabaseDriver and the host's configured key type
if (DatabaseDriver::current()->isPgsql()) {
    // …
}
$table->ownerKey('author_id', KeyType::fromConfig('comments.key_type'));

3. Replace local helper copies

Replace any local LikeEscaper, config-guard or model-resolver copies with the toolkit’s Support helpers — LikeEscaper, Config and ModelResolver.

4. Run the quality gate

Run the package’s tests and static analysis, then CI:

composer test
composer analyse

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.