lavaphp / app
LavaPHP application skeleton — the composer create-project target. Boots green with zero configuration.
Requires
- php: ^8.3
- lavaphp/core: ^0.4.0
Requires (Dev)
- phpunit/phpunit: ^12.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
The LavaPHP application skeleton — and the composer create-project target.
There is no src/ here: this is the app. Everything the framework reads is a
file you can open, and nothing is wired by convention.
Create an app
composer create-project lavaphp/app my-app
cd my-app
The skeleton requires only lavaphp/core. Add a pack when the app needs one —
composer require lavaphp/db — and enable it in app/Modules.php.
Run it
lava check # boot, wiring, routes, features, env, commands, the map, and the suite lava serve # php -S on public/index.php lava test # the app's own PHPUnit
lava check is the one command to run first — and the one to run after every
change. It reports every problem in the app at once, each with a file:line, the
value that failed, and the fix to apply. lava check --quick is the tight loop
(boot's own findings only, no suite, under two seconds).
Add --json to any command for a machine-readable envelope.
The layout
| path | what it is |
|---|---|
app/Routes.php |
every route, registered explicitly |
app/Services.php |
every service, built by visible code — no auto-wiring |
app/Modules.php |
the packs this app loads |
app/Middleware.php |
the middleware wrapping every route |
app/Commands.php |
(optional) this app's own lava commands |
config/ |
app.php, features.php, logging.php, and .env |
public/index.php |
the HTTP entry point — the one file that is not optional |
tests/ |
the app's suite; lava test and lava check run it |
AGENTS.md is generated by lava map from the app's own registries — its routes,
services, flags, commands, environment variables, and the canonical minimal form
of every artifact you can write. It ships pre-generated and accurate, so an agent
(or a person) has a current map from the first moment after composer install.
Change the app and run lava map; lava check warns when it has gone stale.
Handler contract
A handler class is constructed with no arguments; its dependencies arrive as typed method parameters:
public function show(RouteArgs $args, Greeter $greeter): ResponseInterface
Only three parameter kinds are injectable — the request, RouteArgs, and a
registered container id — and the return type must be ResponseInterface. Boot
checks all of this and reports bad_handler naming the signature to write, rather
than failing at request time.
Working on this skeleton inside the monorepo
composer.json carries no repositories block, and must not: it is the file
composer create-project lavaphp/app hands a consumer, and a path repository there
would point at a ../core that does not exist in their project. Composer fails
a root package's install outright rather than falling back to Packagist.
So inside the monorepo the skeleton is installed the way CI installs it — copied next to the packages it needs, and given path repositories to them in the copy. From the repository root:
composer check:install -- app