noirapi / framework
Small PHP 8.4 web framework: FastRoute routing, Latte views, noirapi/database models, Tracy debugging.
Requires
- php: ^8.4
- ext-json: *
- ext-mbstring: *
- ext-pdo: *
- ext-posix: *
- bacon/bacon-qr-code: ^2.0.8 || ^3.0
- html2text/html2text: ^4.3
- laminas/laminas-permissions-acl: ^2.10
- latte/latte: ^3.1
- nette/neon: ^3.4
- nette/schema: ^1.3
- nette/utils: ^4.0
- nikic/fast-route: ^1.3
- nikic/php-parser: ^5.0
- noirapi/database: ^5.0
- php-curl-class/php-curl-class: ^9.1 || ^10.0 || ^11.0 || ^12.0 || ^13.0
- robthree/twofactorauth: ^2.0 || ^3.0
- symfony/mailer: ^7.0 || ^8.0
- tracy/tracy: ^2.10
Requires (Dev)
- pdepend/pdepend: 3.x-dev@dev
- phpmd/phpmd: 3.x-dev@dev
- phpunit/phpunit: ^12.0
- rector/rector: ^2.2
- squizlabs/php_codesniffer: ^4.0
Suggests
- ext-memcached: Memcached session handler (session.driver: memcached)
- ext-pdo_mysql: MySQL / MariaDB models and the MySQL session handler
- ext-pdo_sqlite: SQLite models and the SQLite session handler
- ext-swoole: Serving the app with swoole.php and Lib\Tasks
- digitickets/lalit: XML responses (Response::TYPE_XML)
- rector/rector: Automated upgrades with Rector/config/*.php (see UPGRADE.md)
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-28 16:33:47 UTC
README
Small PHP 8.4 web framework: FastRoute routing, Latte views, noirapi/database models, Tracy debugging, NEON config, and pluggable auth (password, magic link, TOTP, GitHub/Google OAuth).
Package: noirapi/framework, namespace Noirapi\, PHP ^8.4, MIT.
Installation
There are two supported layouts, and they run the same code (Noirapi\Lib\Kernel).
Composer (new projects)
composer require noirapi/framework
Stability:
noirapi/frameworkdepends onnoirapi/database ^5.0, which is in beta until 5.0.0 is tagged. Until then the project'scomposer.jsonneeds:"minimum-stability": "beta", "prefer-stable": true
Project layout. Every path is relative to the project root, which the kernel is given:
myapp/
app/
Route.php App\Route: process($method, $uri) -> FastRoute dispatch result
controllers/ models/ views/ layouts/
config/default.neon picked by the CONFIG env var, else the virtual host name, else "default"
htdocs/index.php web root
temp/ logs/ must exist and be writable (Latte/config cache, Tracy logs)
data/ SQLite databases with relative DSNs
vendor/
composer.json "autoload": {"classmap": ["app/"]}
htdocs/index.php:
<?php declare(strict_types=1); require dirname(__DIR__) . '/vendor/autoload.php'; Noirapi\Lib\Kernel::run(dirname(__DIR__));
CLI scripts only boot (config, timezone, sessions, Tracy):
require __DIR__ . '/../../vendor/autoload.php'; Noirapi\Lib\Kernel::boot(__DIR__ . '/../..');
Tools are exposed as one Composer binary:
vendor/bin/noirapi dev-server start [--port 8000] [--host localhost] [--config NAME] vendor/bin/noirapi dev-server stop|restart|status vendor/bin/noirapi latte-lint app/views vendor/bin/noirapi latte-check [--strict] [--no-controller-check]
git submodule (existing projects)
Existing apps keep the framework checked out at <root>/noirapi/ and use the legacy entry points,
which are thin shims over the same kernel:
require dirname(__DIR__) . '/noirapi/kernel.php'; // htdocs/index.php and CLI scripts require dirname(__DIR__) . '/noirapi/include.php'; // bootstrap only
noirapi/bin/dev-server start noirapi/bin/latte-lint app/views php noirapi/bin/latte-check.php
See UPGRADE.md for what a submodule app needs when it updates to 1.x, and for moving it to the Composer layout.
How the application root is found
Noirapi\Config::getRoot() resolves, in order:
- the root passed to
Kernel::run()/Kernel::boot(); - the
NOIRAPI_ROOTenvironment variable (vendor/bin/noirapianddev-serverset it); - the submodule layout: the framework's parent directory, when it contains
app/; - the Composer layout: the root of the Composer install that contains
noirapi/framework.
The framework's own files (bundled templates, bin scripts) are found with Config::getFrameworkDir().
Documentation
Development
composer install composer test # PHPUnit: root detection + Rector rule fixtures
Releases are tagged vX.Y.Z on master. CI (.github/workflows/ci.yml) runs the tests and
then notifies Packagist; it needs the PACKAGIST_USERNAME and PACKAGIST_TOKEN repository secrets.