mnapoli/silly
Silly is a micro-framework for building PHP command-line applications on top of Symfony Console. Commands are defined with simple callables and signatures like 'greet [name] [--yell]', while dependency injection, console helpers, and PHP-DI or Pimple integration are included.
configure(), execute(), argument/option wiring, input validation) into a single $app->command('greet [name] [--yell]', fn(...) => ...) expression. The decision to expose an operation as a command becomes roughly "one line plus a closure" instead of "a day of boilerplate," which changes the economics of shipping operational tooling at all.Symfony\Console\Application, so commands run without booting Laravel (avoiding the ~100ms+ framework boot for a script that takes 20ms of real work). This supports the decision to ship runbook/ops CLIs, migration runners, and CI helpers as standalone Composer binaries in repos that are not Laravel apps — including polyrepo fleets where dragging a Laravel skeleton in would be indefensible.bin/ substrate. If the roadmap includes publishing a library or OSS tool that needs a console entry point, adopting Silly is a decision to ship a binary without forcing a framework dependency on your consumers.Consider adopting it when:
$input, $output, SymfonyStyle, setDefaultCommand(), and the whole Symfony Console ecosystem remain available with zero migration path, so the escape hatch is real.bin/.[name], [--yell], [--age=], --option=*, hyphen-to-camelCase mapping, defaults inferred from closure parameters) is the lowest-friction argument definition available in PHP.Look elsewhere when:
Adoption checklist before committing:
For executives (one paragraph): We can cut the cost of internal operational tooling from project-shaped to task-shaped. Silly is a small, MIT-licensed, actively maintained library that lets engineers define a working command-line tool in a single line over services we already have, without standing up or booting a full application. That means faster validation of roadmap ideas (ship the CLI first, build the UI only if usage earns it), lower infrastructure cost for scripts that don't need a framework, and no new licensing spend. It's proven in widely used tools including Bref and Laravel Valet, and the risk is contained: it's ~900 stars, small enough to vendor, and a two-day swap to plain Symfony Console if we ever outgrow it.
For engineering (the ask): Standardize on Silly for standalone console binaries — repos that are not Laravel apps, distributed Composer tools, ops/migration/CI scripts — and explicitly not for commands inside the Laravel app, which stay in Artisan. Rationale: one-line command definitions, DI inside closures via any PSR-11 container, full Symfony Console compatibility (so $input, $output, SymfonyStyle, and setDefaultCommand() remain available), and no framework boot on the hot path. Two rules come with it: commands are thin adapters over services, never containers of business logic, and every command returns an explicit exit code with test coverage. If the tool grows config loading, plugin support, or rich TTY interaction, we graduate to Laravel Zero or full Symfony Console — a small, well-understood migration because the container and command signatures carry over.
How can I help you explore Laravel packages today?