sala/console
Sala Console is a Laravel package for building and organizing custom console commands and interactive CLI workflows. It simplifies command registration and provides clean output helpers for everyday development tasks.
sala/console is the console layer for the Sala framework (salaab/framework and derived projects), not a drop-in Artisan replacement for vanilla Laravel. It uses Illuminate components and Eloquent under the hood, but commands, migrations, and bootstrapping are its own.
Minimum setup:
composer require sala/console:^1.0
php bin/console list
If bin/console is not in the project root, use vendor/bin/console list. Confirm the 20 commands are registered, then inspect individual command contracts with:
php bin/console help make:model
php bin/console help migrate
Look here first:
config/console.php — command registration, paths, serve settings, and likely DB/Phinx wiring.stubs/ — templates used by every make:* generator.bin/console — universal bootstrap: project-root detection, .env loading, config/*.php loading, and Eloquent bootstrap.#[AsCommand] — the extension point for adding your own commands.A good first end-to-end use case is scaffolding one feature:
php bin/console config:publish
php bin/console stub:publish
php bin/console make:model User
php bin/console make:migration CreateUsersTable
php bin/console migrate
php bin/console make:repository UserRepository
php bin/console make:service UserService
php bin/console make:controller UserController
php bin/console make:view users/index
php bin/console seed:run
php bin/console serve
For interactive work:
php bin/console tinker # alias: shell
Then try db()->table('users')->count(), inspect $config, or query an Eloquent model directly. Tinker preloads $app and $config, provides a db() helper, Eloquent casters for Model/Collection, and stores history per project under storage/psysh.
bin/console supports standalone use, being copied into the consumer project root, or being called as vendor/bin/console. Pick one per project and use it consistently in docs, Composer scripts, and CI. Prefer vendor/bin/console when possible so package upgrades are picked up automatically; a copied root-level bin/console can drift from the installed package version.
Typical Composer scripts:
{
"scripts": {
"console": "bin/console",
"serve": "bin/console serve",
"migrate": "bin/console migrate",
"test": "vendor/bin/pest"
}
}
Run config:publish and stub:publish once, review the output, and commit the published files. Generated classes and views inherit whatever is in the published stubs, so this is the main lever for enforcing team conventions: namespaces, base classes, docblocks, repository/service interfaces, and view layout.
After publishing:
config/console.php points at the published stub directory, not the package default.--force; avoid overwriting customized files blindly.| Task | Sala console | Laravel analogue |
|---|---|---|
| Dev server | serve |
php artisan serve |
| Create database | db:create |
manual SQL / db:create in some stacks |
| Drop database | db:drop |
manual SQL |
| Migrate | migrate |
migrate |
| Roll back | rollback |
migrate:rollback |
| Migration status | status |
migrate:status |
| Toggle migration | breakpoint |
none directly |
| Seed | seed:run |
db:seed |
| Migration generator | make:migration |
make:migration |
| Model/controller/middleware | make:model, make:controller, make:middleware |
same names |
| Repository/service/view | make:repository, make:service, make:view |
not built into Laravel |
| Publish assets | stub:publish, config:publish |
vendor:publish |
| REPL | tinker / shell |
tinker |
| Export DB | db:export |
mysqldump manually |
Notably absent: make:command, migrate:fresh, migrate:refresh, db:wipe, and db:import. Plan around those gaps rather than assuming Artisan parity.
A practical workflow is model → migration → repository → service → controller → view, with migrate and seed:run between stages. Because generators are stub-driven, adjust stubs first if the team has standard interfaces or base classes; otherwise you will edit every generated file.
For migrations, remember the generator produces Phinx migrations, not Laravel migration classes. Expect Phinx\Migration\AbstractMigration, $this->table(...), and Phinx column APIs rather than Schema::create.
Commands are registered via #[AsCommand] (Symfony Console 7). A custom command looks like:
#[AsCommand(name: 'reports:daily', description: 'Generate the daily report')]
final class DailyReportCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
// ...
return Command::SUCCESS;
}
}
Define arguments and options in configure(); there is no Laravel protected $signature. Register the class in config/console.php (verify the exact key in the published config) and ensure it is autoloadable. If it does not appear in bin/console list, registration or autoloading is the first thing to check.
Tinker is the fastest feedback loop for DB and Eloquent work:
db()->table('users')->where('active', 1)->count();
$config['database']; // inspect loaded config
App\Models\User::with('posts')->first();
Treat $app as the Sala application instance, not Illuminate\Foundation\Application. Do not assume app()->make(), config(), or env() helpers exist. The db() helper and Eloquent casters are the supported conveniences.
Add storage/psysh to .gitignore, and be aware that history may contain sensitive query values.
A reasonable local and CI sequence:
php bin/console db:create
php bin/console migrate
php bin/console seed:run
php bin/console db:export
For CI, run commands from the project root, provide a valid .env, and use non-interactive flags where available. Verify how Phinx environment selection works (-e or config-driven) before assuming APP_ENV alone switches databases. db:export is useful for fixtures and snapshots, but there is no matching import command; restoring is a manual client operation.
php artisan. There is no artisan binary, no migrate:fresh, no make:command, and no db:seed naming. Build scripts against bin/console or vendor/bin/console.rollback and breakpoint follow Phinx semantics; confirm whether rollback targets the last batch or a specific version before running against shared databases.php ^8.4. Many Laravel/Sala deployments still run PHP 8.2 or 8.3; Composer will refuse installation there. Check platform constraints in CI and production images before adopting. This constraint is stricter than the illuminate/* ^10|^11|^12 range suggests.^1.0 and read changelogs before minor upgrades.bin/console root detection can surprise you. Auto-detection of the project root, .env, and config/*.php may behave differently when invoked from a subdirectory, a cron job, a symlink, or vendor/bin. Always run from the project root in scripts, and test cd public && ../bin/console list if you rely on relative paths.config(), env(), app(), and facades are not guaranteed outside Tinker. The db() helper is a Tinker convenience; do not design production code around it. Use explicit connections/models or the Sala framework's own abstractions.config/console.php loads project config, while Phinx may also expect its own configuration. Keep credentials and database names in one place, and verify migration commands are reading the same values as Eloquent. Mismatches produce confusing "table not found" or "database does not exist" errors.db:drop is destructive. Confirm whether it prompts and which environment/database it targets. Guard it in production scripts and never wire it into an unconditional CI step.db:export depends on external binaries. It likely shells out to mysqldump or pg_dump. Ensure the binary exists in the runtime image, credentials are passed via environment rather than the command line, and output paths are writable and gitignored. There is no db:import; document the restore procedure.serve is development-only. It likely wraps PHP's built-in server. Do not use it in production, and verify host, port, and document root settings in config/console.php if assets or routing behave oddly.sala/console does not update files you published. New config keys or improved stubs will be missed. Periodically re-publish to a temporary directory and diff against your committed versions.config:publish and stub:publish support --force or prompt per file. Keep published files under version control so mistakes are recoverable.storage/psysh may be unwritable or owned by the wrong user. Locally, history can capture sensitive queries; clear it before sharing a workspace or screen.#[AsCommand] class that is not registered or not autoloaded simply will not appear in list. Check config/console.php, Composer autoload, and command name collisions with built-ins.How can I help you explore Laravel packages today?