Simplicity and Consistency
An entity-centered framework. Declare your domain structure once and Nyoze handles routes, validation, and persistence.
Consistency from start to finish.
class UserEntity extends EntityDefinition
{
public function define(Entity $entity): void
{
$entity
->fields(
Field::string('name')->required(),
Field::email('email')->unique(),
Field::password('password')->hidden(),
)
->can('profile', ProfileAction::class)
->invariant(EmailRequired::class);
}
}
Consistency
Entity-centered model. One pattern. Every project.
Entity as the core
Fields, relations, and constraints declared in one place. The system organizes itself from that definition.
Structural standardization
Entities define structure, actions define behavior, repositories handle data. No variation.
Predictability
Any developer can locate any part of the code without guidance. The pattern speaks for itself.
Simplicity
Fewer concepts, fewer files, fewer decisions.
Reduced complexity
No manual routes, no service providers, no scattered configs. The entity declares, the framework resolves.
Clear readability
An entity reads like a specification. Fields, actions, and rules visible in a single file.
Lower cognitive cost
The developer focuses on the domain, not on framework infrastructure.
How it works
The entity is the core. Everything starts from it.
Define the entity
Fields, types, and constraints with a fluent API.
$entity->fields(
Field::ref('id_user', 'users'),
Field::string('title')->required(),
Field::string('status')->default('draft'),
);
Connect the behavior
Each ->can() becomes an HTTP endpoint.
$entity
->can('create', CreateAction::class)->post()
->can('list', ListAction::class)->get();
Isolate the logic
One action, one ActionContext, one Result.
class CreateAction
{
public function __invoke(ActionContext $ctx): Result
{
$project = $ctx->repo()->save('projects', [
'title' => $ctx->input('title'),
'id_user' => $ctx->userId(),
]);
return Result::created($project);
}
}
Run it
Kernel, repository, entities. Done.
$kernel = Kernel::load(function (App $app) {
$app->useRepository(
new PdoRepository(new PDO('sqlite:app.db'))
);
$app->load([UserEntity::class]);
});
$kernel->app()->run();
Database & Migrations
Pluggable providers, automatic schema, and integrated CLI.
Pluggable providers
MySQL, SQLite, or your own provider. SQL generation is decoupled — switch databases without changing entities.
Automatic schema
Nyoze reads your entities and generates SQL migrations automatically. No manual DDL writing.
Configurable IDs
Snowflake, AutoIncrement, UUID, or ULID. Choose the strategy globally or per entity.
Integrated CLI
Generate migrations, execute, rollback, and inspect the schema directly from the terminal.
Fluent configuration
Configure the database with a single call. The provider, connection, and ID strategy are centralized.
$app->database()->mysql([
'host' => '127.0.0.1',
'database' => 'myapp',
'user' => 'root',
'pass' => 'secret',
]);
CLI
Generate, execute, and manage migrations without leaving the terminal.
# make:migration
$ php nyoze make:migration
# migrate
$ php nyoze migrate
# migrate:rollback
$ php nyoze migrate:rollback
# schema:dump
$ php nyoze schema:dump
Concrete benefits
Easy maintenance
Predictable structure. Any developer navigates the project without additional learning curve.
Controlled scalability
Adding entities always follows the same process. The project grows without technical debt.
Temporal consistency
From the first endpoint to the hundredth, the pattern is the same.
Decoupled persistence
Switch databases without changing business logic.
No lock-in
No proprietary ORM, no globals. Portable domain code.
HTTP and CLI
Same entities, same actions. Two execution modes.
Independent project, maintained with personal time. If Nyoze makes sense in your workflow, a coffee helps keep everything moving.
Buy me a coffeeConsistency from start to finish.
$ composer require pollauf/nyoze