Package Scaffold
Primary Goal
Add package features in the right place and wire them through the service provider using explicit Laravel APIs, keeping package names, namespaces, config keys, and publish tags consistent.
Workflow
- Inspect the existing package structure, sibling examples, README setup notes, and the current service provider before creating files.
- Identify whether the request touches commands, migrations, routes, config, views, translations, assets, middleware, tests, README/contributing docs, compatibility, or release flow.
- Create the capability files under Laravel-native package paths and use the configured package names, namespaces, publish tags, URLs, and badges consistently.
- Wire the capability through the service provider using the patterns in Provider wiring below.
- Use
package-testingfor coverage, update README or contributing documentation when user-facing behavior changes, usepackage-compatibilityfor matrix-sensitive changes, and usepackage-releasefor release tasks. - Add only the files needed for the requested capability and validate with the narrowest relevant command before broader checks.
Provider Wiring
- Keep provider wiring in
register()orboot()unless extracting a method makes a real repeated concern clearer. - Put container bindings and
mergeConfigFromcalls inregister()when the host app must be able to override configuration. - Put resource loading in boot-time methods with Laravel-native APIs such as
loadRoutesFrom,loadViewsFrom, andloadTranslationsFrom. - Guard console-only publishing and command registration with
runningInConsole()before callingpublishes,publishesMigrations, orcommands. - Name publish tags with the
waitlist-*convention so consumers can target individual resource groups. - Add tests for the observable provider behavior: merged config, loaded routes, publish tags, or command registration.
Provider wiring anti-patterns:
- Loading host app state too early during provider registration.
- Calling
env()outside config files; use config values aftermergeConfigFrominstead. - Registering web-only concerns unconditionally when the package can run in console contexts.
- Replacing explicit provider methods with
spatie/laravel-package-toolsby default.
References
src/*ServiceProvider.phpconfig/*.phproutes/*.phpresources/views/lang/database/migrations/public/src/Console/Commands/tests/Feature/andtests/Unit/
Examples
- Add an Artisan command: create the command class under
src/Console/Commands, register it in thecommandsarray inside therunningInConsole()guard, add a feature test for observable console output, and document the command if it is user-facing. - Add a publishable migration: place the migration in
database/migrations, wire it through a console-guardedpublishesMigrationscall with awaitlist-migrationstag, and test publish behavior with Testbench. - Wire a new publish tag by adding a
publishesmap inside the existing console-guarded publishing method and naming the tag withwaitlist-*.
Anti-Patterns
- Adding unused files because a package might need them later.
- Mixing package names, namespaces, config keys, or publish tags.
- Changing dependencies without approval.
- Replacing explicit Laravel package code with a helper abstraction when one feature-specific change would do.