michael-rubel/laravel-package-template
A minimal starter skeleton for building Laravel packages, with preconfigured boilerplate for service providers, configuration files, tests, and Composer metadata so you can scaffold a new package quickly and focus on writing your own code instead of setup.
michael-rubel/laravel-package-template is not a runtime dependency — it is a GitHub template repository for scaffolding a distributable Laravel package. The 1.0 tag is the template's own stability milestone, so "getting started" means generating a repo from it, not composer require-ing it.
Two entry points:
# Preferred: keeps .github/, LICENSE, README, .editorconfig, Dependabot config
# Use the "Use this template" button on GitHub, then clone your new repo.
# Alternative: one-shot scaffold, no repo metadata carried over
composer create-project michael-rubel/laravel-package-template my-package
Where to look first, in order:
composer.json — name, autoload.psr-4 namespace, require/require-dev constraints, extra.laravel.providers.src/ — the service provider and the example class/facade you will rename or delete.tests/TestCase.php + phpunit.xml.dist — Orchestra Testbench wiring; this is the piece most people break first..github/workflows/ — the test matrix, static analysis, and style jobs that define your CI contract.First use case: install, confirm the baseline is green, then rename.
composer install
vendor/bin/pest # or vendor/bin/phpunit
vendor/bin/pint --test
Rename by substitution, not by hand. Grep for the template's vendor/package strings and namespace before writing a line of domain code:
grep -rl 'MichaelRubel\\PackageTemplate' src tests config database | xargs sed -i '' 's/.../YourVendor\\\\YourPackage/g'
grep -rl 'laravel-package-template' . --exclude-dir=vendor
composer dump-autoload
Then run the test suite again — a green baseline after renaming is your proof the autoload map is consistent.
Let the service provider do the loading, then prune. The template pre-wires mergeConfigFrom, loadMigrationsFrom, loadTranslationsFrom, loadViewsFrom, publish tags, and command registration. Delete the blocks you don't need rather than adding your own — duplicated loading is the most common source of double-registered routes and duplicate migration runs. If it is based on spatie/laravel-package-tools, everything lives in a single configurePackage() call and reads as a manifest.
Testbench is the dev harness. tests/TestCase.php boots a throwaway Laravel app; getPackageProviders() and getPackageAliases() are where you register your provider and facade. For manual exploration, add a workbench/ app and vendor/bin/testbench serve rather than creating a separate Laravel install.
Facades get @see docblocks. The template's src/Facades/*.php pattern relies on a @method/@see block pointing at the underlying class so IDEs and Larastan resolve static calls. Keep that block in sync when you add public methods, or static analysis starts reporting false positives.
Namespace your publish tags. Prefix tags with the package slug (your-package-config) so vendor:publish --tag= never collides in a host app that has many packages installed.
Sync with upstream instead of re-templating. Keep the template reachable as a second remote so CI and tooling fixes land in existing packages:
git remote add template https://github.com/michael-rubel/laravel-package-template.git
git fetch template && git merge template/main --allow-unrelated-histories
Expect conflicts in composer.json, workflows, and README — resolve by taking upstream for .github/ and yours for metadata.
0.1...1.0 is the only source of truth. Before adopting, diff composer.json (PHP/Laravel/Testbench constraints), .github/workflows/, and the provider — a major bump on a template almost always means raised minimums and reworked CI, both of which are breaking for repos that merged upstream.composer require this in an application. There is no meaningful runtime API; requiring it just adds a stray provider and dev dependencies to production autoloading.composer dump-autoload plus clearing the host app's bootstrap/cache/ is required. Symptoms of skipping it: Class not found, or the old provider still listed in a cached packages.php.config:cache silently masks mergeConfigFrom. Changes to your defaults won't appear in a consuming app until the cache is rebuilt, and published configs never pick them up again. Document vendor:publish --force and config:clear in the README.laravel/framework without bumping orchestra/testbench produces confusing container/bootstrap failures, not a clear version error.phpstan-baseline.neon only for genuine framework stubs, not for your own unresolved types.contents: write in repo settings or the job fails with a permissions error that looks like a style failure.0.1.0 and follow semver from your first tagged release.How can I help you explore Laravel packages today?