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

Package Wizard Laravel Package

andrey-helldar/package-wizard

Package Wizard is an interactive CLI tool for Laravel and PHP developers that scaffolds new packages. It guides you through setup questions and generates the boilerplate—composer.json, service provider, config, tests, and docs—so you can start building instead of wiring structure by hand.

View on GitHub
Deep Wiki
Context7

Getting Started

Install (one-time, global). Package Wizard is an interactive CLI, so it belongs on your PATH, not in a project's require-dev:

composer global require andrey-helldar/package-wizard
# ensure the global bin dir is on PATH:
export PATH="$PATH:$HOME/.config/composer/vendor/bin"   # or ~/.composer/vendor/bin on older setups
package-wizard

If you'd rather not pollute the global namespace (recommended, since the package is archived since 2021), install it into a throwaway "toolbox" project and run it from there:

mkdir ~/tools && cd ~/tools && composer require --dev andrey-helldar/package-wizard
php vendor/bin/package-wizard

First run, first use case. Scaffold one package in a scratch directory before you trust it inside a real repo — you want to see exactly what files it writes and where:

mkdir /tmp/pkg-test && cd /tmp/pkg-test
package-wizard
# prompts: vendor/package name, namespace, author name + email, description, license

Where to look first, in this order:

  1. composer.json — the autoload.psr-4 mapping and extra.laravel.providers. These two are what make the package actually loadable and auto-discoverable.
  2. The generated service provider under src/ — check it registers config, migrations, views, or translations if you intend to ship any.
  3. config/ — confirm the publish path uses __DIR__.'/../config/...', not a hardcoded path.
  4. tests/ + phpunit.xml — the "ready-to-run testing setup" is the biggest time saver; verify it actually runs (vendor/bin/phpunit) before adding your own code.
  5. git init && git add -A && git commit -m "scaffold" — this baseline commit is your diff target for every manual fixup you make next.

Then immediately: composer validate --strict, composer install, composer dump-autoload -o, and run the test suite once. If those three pass, the skeleton is sound.

Implementation Patterns

Two integration shapes. Decide up front which one you're in, because the post-generation steps differ.

Standalone repo (most common):

cd ~/code && package-wizard     # generates into a new directory named from vendor/package
cd my-vendor-my-package
composer install && vendor/bin/phpunit
git remote add origin [email protected]:me/my-package.git

Monorepo / path repository. Generate into packages/<vendor>/<name>, then in the host app's composer.json:

{
  "repositories": [{ "type": "path", "url": "packages/*", "options": { "symlink": true } }]
}
composer require my-vendor/my-package:@dev

The symlink means edits in packages/ are live in the app — the fastest loop for package development. Drop the path repository before tagging a release.

The 10-minute post-scaffold hardening checklist. The wizard gets you 80% there; these are the pieces you almost always touch:

  • Namespace consistency: grep -rn "OldNamespace" . after any rename (see gotchas).
  • mergeConfigFrom(__DIR__.'/../config/name.php', 'name') in the provider plus $this->publishes([...], 'name-config') — defaults merged, user overrides publishable.
  • loadMigrationsFrom, loadViewsFrom(__DIR__.'/../resources/views', 'name'), loadTranslationsFrom — add only what you ship.
  • extra.laravel.providers in composer.json for Laravel 5.5+ auto-discovery.
  • illuminate/support constraint widened to what you actually test against (e.g. ^8.0|^9.0|^10.0), not whatever the archived generator wrote.
  • orchestra/testbench in require-dev with a TestCase that declares getPackageProviders() — the generated test harness usually needs this shim to boot a Laravel container.

Use Testbench, not a full app, for the dev loop.

abstract class TestCase extends \Orchestra\Testbench\TestCase
{
    protected function getPackageProviders($app): array
    {
        return [\MyVendor\MyPackage\ServiceProvider::class];
    }

    protected function getPackageAliases($app): array
    {
        return ['MyPackage' => \MyVendor\MyPackage\Facades\MyPackage::class];
    }
}

This is the single highest-leverage change you'll make to the generated skeleton.

Treat the generated output as your template, not the tool as your generator. Because the project is archived, the durable pattern is: scaffold once with the wizard, hand-fix it to your current standards, then commit that repo as skeletons/laravel-package and duplicate it (git clone + git remote remove origin + rename script). You get repeatability without depending on a frozen dependency.

Renaming script (worth keeping next to the template):

OLD_NS="Old\\Vendor"; NEW_NS="New\\Vendor"
grep -rl "$OLD_NS" --include="*.php" --include="*.json" . | xargs sed -i "s/$OLD_NS/$NEW_NS/g"
composer dump-autoload -o && vendor/bin/phpunit

CI from day one. Add a matrix immediately after scaffolding — this is what catches the "generated against PHP 7.4 but I'm on 8.2" problem early:

strategy:
  matrix:
    php: ['8.1', '8.2', '8.3']

with composer validate --strict and vendor/bin/phpunit as steps.

Gotchas and Tips

It's archived — pin your expectations, not just your versions. Last release May 2021 means the generated composer.json, PHPUnit config, and CI stub reflect the Laravel 8 / PHP 7.4–8.0 era. Budget 15 minutes to bump illuminate/support, orchestra/testbench, and phpunit/phpunit to current constraints before writing a line of real code. Don't expect fixes upstream.

Prompt typos are silent and expensive. The wizard asks for the vendor/package name and the PHP namespace separately, and it derives PSR-4 paths from the namespace. A mismatch produces a package that installs fine and then fails with a bare Class not found. Verify immediately:

composer dump-autoload -o
php -r "require 'vendor/autoload.php'; var_dump(class_exists('Your\\Namespace\\ServiceProvider'));"

If that's false, fix the namespace before git commit — it's a one-line sed now and a 40-file refactor later.

No documented non-interactive mode. If you want CI/automation scaffolding, don't fight the prompts — copy your committed skeleton repo instead. If you must drive it, feed answers via stdin (printf 'vendor\npackage\n...' | package-wizard) and check in /tmp first, since prompt order can change between versions.

Check where it writes before running it inside a repo. Run it once in an empty /tmp directory to see whether it creates a subdirectory or writes into the CWD. Running it in the wrong place scatters src/, config/, and composer.json into your existing project.

Config that "doesn't work" is usually a merge-vs-publish problem. If config('name.key') returns null in a consuming app, the provider is missing mergeConfigFrom. If user overrides are ignored, the package is publishing to the wrong tag or the app hasn't run php artisan vendor:publish --tag=name-config. Test both paths in Testbench.

Auto-discovery doesn't apply in tests. extra.laravel.providers only fires when a Laravel app installs the package. Inside your own test suite nothing is discovered — hence the getPackageProviders() override above. Confusing "provider not registered" errors during package tests almost always trace back to this.

Global install shadowing. A globally installed wizard plus a per-project require-dev copy can resolve to different versions and different prompt sets. Pick one. On Windows there's no vendor/bin on PATH by default — use php vendor\bin\package-wizard.

Debugging the generator itself: run with -vvv for Symfony Console verbosity, and read the stub templates shipped inside the package (look under src/ and any resources//stubs/ directory in the installed package). Since it's archived, the fastest way to change generated output — extra files, stricter composer.json, a modern CI workflow — is to fork the repo and edit the stubs, then composer require your fork. That's the real extension point; there's no plugin API.

Skip composer.lock in the package repo. Libraries shouldn't commit a lockfile — it pins transitive deps for consumers. Keep the lock only in the host app or monorepo root.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo