PHPackages                             lucaskaiut/orkestri - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. lucaskaiut/orkestri

ActiveLibrary[Framework](/categories/framework)

lucaskaiut/orkestri
===================

Opinionated architectural scaffold generator for Laravel.

1.0.0(2mo ago)03MITBladePHP ^8.1

Since Feb 19Pushed 2mo agoCompare

[ Source](https://github.com/lucaskaiut/orkestri)[ Packagist](https://packagist.org/packages/lucaskaiut/orkestri)[ RSS](/packages/lucaskaiut-orkestri/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (2)Used By (0)

Orkestri
========

[](#orkestri)

**Opinionated architectural scaffold generator for Laravel.**

Orkestri generates a consistent, module-based structure for Laravel applications. Each module contains Domain (Models, Services), HTTP (Controllers, Requests, Resources), Database (Migrations), and API routes. Generated controllers and services use built-in traits and contracts so you get a working CRUD API skeleton without writing boilerplate.

---

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Web UI](#web-ui)
- [Configuration](#configuration)
- [How It Works](#how-it-works)
- [Commands](#commands)
- [Generated Structure](#generated-structure)
- [Architecture](#architecture)
- [Stubs](#stubs)
- [Testing](#testing)
- [License](#license)

---

Requirements
------------

[](#requirements)

- **PHP** ^8.1
- **Laravel** 10.x, 11.x or 12.x (auto-discovered via Composer)

---

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require lucaskaiut/orkestri
```

The package registers its service provider automatically (Laravel package discovery). No need to add it to `config/app.php`.

---

Web UI
------

[](#web-ui)

After installing the package, a web route called /orkestri/modules is available for creating and managing modules via the browser. You can define the module name and its fields, create the module, run migrations from the UI, and obtain a fully functional CRUD API with the same generated architecture (controllers, services, models, migrations, resources, requests, and API routes).

### Module list

[](#module-list)

The module list shows all created modules. For each module you can run the migration directly from the UI. Modules that have not yet been migrated show a button to execute the migration; after running it, the list reflects the migrated state.

Pending migrationMigration executed[![Module list with migrate button](assets/module_grid_migrate.png)](assets/module_grid_migrate.png)[![Module list with migration executed](assets/module_grid_migrated.png)](assets/module_grid_migrated.png)### Creating a module

[](#creating-a-module)

Use the creation form to set the module name and define its fields (name and type). The UI generates the corresponding migration columns and the full module structure.

[![Module creation form with fields](assets/module_form.png)](assets/module_form.png)

### Module view

[](#module-view)

Once a module is created and its migration has been run, you get a ready-to-use CRUD endpoint. The module view summarizes the generated structure and the available API.

[![Module view](assets/module_view.png)](assets/module_view.png)

Workflow: **Create module (name + fields) → Run migration (UI) → Use the CRUD API** with no extra manual scaffolding.

---

Configuration
-------------

[](#configuration)

Publish the config file to customize where modules live and which folders each module has:

```
php artisan vendor:publish --tag=orkestri-config
```

This creates `config/orkestri.php`:

KeyDefaultDescription`base_path``'Modules'`Directory under `app/` where modules are created (e.g. `app/Modules/Customer` or `app/Domains/Customer`).`structure`See belowList of relative paths created inside each module.**Default `structure`:**

```
'structure' => [
    'Domain/Models',
    'Domain/Services',
    'Database/Migrations',
    'Http/Controllers',
    'Http/Requests',
    'Http/Resources',
],
```

All commands respect `base_path` and `structure`. Changing `base_path` to e.g. `'Domains'` makes modules appear under `app/Domains/{ModuleName}` and updates namespaces accordingly.

---

How It Works
------------

[](#how-it-works)

- **Routes:** The service provider scans `app/{base_path}/{Module}/Http/Routes/` and loads `api.php` for each module. No manual `RouteServiceProvider` wiring per module.
- **Migrations:** It also loads migrations from `app/{base_path}/{Module}/Database/Migrations/` so module migrations run with `php artisan migrate`.

Generated controllers use a **ControllerTrait** (index, show, store, update, destroy) and delegate to a **Service**; services implement **ServiceContract** via **ServiceTrait** and are bound to a **Model**. So a new module is a ready-to-use CRUD API scaffold.

---

Commands
--------

[](#commands)

All commands are namespaced under `orkestri:`.

### Create a full module

[](#create-a-full-module)

Creates the folder structure and all default files (service, model, migration, controller, resource, request, API routes).

```
php artisan orkestri:make-module {name}
```

**Examples:**

```
php artisan orkestri:make-module Customer
php artisan orkestri:make-module Product
```

- **`name`** — Module name (StudlyCase). Used for folder name, class names, and plural route segment (e.g. `customers`).
- Fails with exit code `1` and message *"Module already exists."* if the module directory already exists (no overwrite).

---

### Create individual components

[](#create-individual-components)

Use these when you want to add another model, service, controller, etc. inside an existing module.

CommandSignatureDescription**Model**`orkestri:make-model {module} {name?}`Creates an Eloquent model in `Domain/Models`. Default `name` = module name. Table name is pluralized (e.g. `Customer` → `customers`).**Service**`orkestri:make-service {module} {name?}`Creates a service implementing `ServiceContract` in `Domain/Services`. Default `name` = `{Module}Service`.**Controller**`orkestri:make-controller {module} {name?}`Creates a controller using `ControllerTrait` in `Http/Controllers`. Default `name` = `{Module}Controller`.**Resource**`orkestri:make-resource {module} {name?}`Creates a JSON API resource in `Http/Resources`. Default `name` = `{Module}Resource`.**Request**`orkestri:make-request {module} {name?}`Creates a FormRequest in `Http/Requests`. Default `name` = `{Module}Request`.**Routes**`orkestri:make-routes {module}`Creates `Http/Routes/api.php` with `Route::apiResource()` for the default controller and plural resource name.**Migration**`orkestri:make-migration {module} {name?}`Creates a migration in `Database/Migrations`. Without `name`, creates `create_{plural_table}_table` (e.g. `create_customers_table`).**Examples:**

```
# Default names (Customer → Customer, CustomerService, CustomerController, etc.)
php artisan orkestri:make-model Customer
php artisan orkestri:make-service Customer
php artisan orkestri:make-controller Customer

# Custom names within a module
php artisan orkestri:make-model Customer Order
php artisan orkestri:make-migration Customer add_status_to_customers_table
```

All of these refuse to overwrite existing files and print an error message instead.

---

Generated Structure
-------------------

[](#generated-structure)

After running:

```
php artisan orkestri:make-module Customer
```

you get (with default `base_path` = `Modules`):

```
app/Modules/Customer/
├── Domain/
│   ├── Models/
│   │   └── Customer.php
│   └── Services/
│       └── CustomerService.php
├── Database/
│   └── Migrations/
│       └── {timestamp}_create_customers_table.php
├── Http/
│   ├── Controllers/
│   │   └── CustomerController.php
│   ├── Requests/
│   │   └── CustomerRequest.php
│   ├── Resources/
│   │   └── CustomerResource.php
│   └── Routes/
│       └── api.php

```

- **Namespaces** follow `App\{base_path}\{Module}\...` (e.g. `App\Modules\Customer\Domain\Models`).
- **API routes** in `api.php` use `Route::apiResource('customers', CustomerController::class)` (pluralized from the module name).
- **Migration** creates/drops the `customers` table (pluralized from the module name).
- **Model** uses table `customers`; **Controller** uses **CustomerService**, **CustomerResource**, and **CustomerRequest**; **Service** uses **Customer** model and **ServiceTrait**/**ServiceContract**.

---

Architecture
------------

[](#architecture)

### ControllerTrait

[](#controllertrait)

Controllers generated by Orkestri use `LucasKaiut\Orkestri\Traits\ControllerTrait`. You must define:

- `protected string $service` — FQCN of the service (e.g. `CustomerService::class`)
- `protected string $resource` — FQCN of the JSON resource (e.g. `CustomerResource::class`)
- `protected string $request` — FQCN of the FormRequest for store/update (e.g. `CustomerRequest::class`)

The trait provides:

- `index(Request $request)` — Paginated list (query params: `filters`, `orderBy`, `per_page`)
- `show($id)` — Single resource
- `store()` — Create (validates with `$request`, runs in DB transaction)
- `update($id)` — Update (validates with `$request`, runs in DB transaction)
- `destroy($id)` — Delete (in transaction)

Responses use your Resource class and appropriate HTTP status codes.

### ServiceContract &amp; ServiceTrait

[](#servicecontract--servicetrait)

Services implement `LucasKaiut\Orkestri\Contracts\ServiceContract` and use `LucasKaiut\Orkestri\Traits\ServiceTrait`. You must define:

- `protected string $model` — FQCN of the Eloquent model (e.g. `Customer::class`)

The trait implements: `create`, `all`, `find`, `findOrFail`, `findBy`, `getBy`, `paginate`, `update`, `delete`, with support for conditions, ordering, relations, and pagination. Filtering in the controller uses the `filters` and `orderBy` query parameters passed into `paginate`/`getBy`.

---

Stubs
-----

[](#stubs)

Templates live in the package under `stubs/`:

StubUsed byMain placeholders`model.stub`make-model`{{ namespace }}`, `{{ model }}`, `{{ table }}``service.stub`make-service`{{ namespace }}`, `{{ module }}`, `{{ service }}``controller.stub`make-controller`{{ namespace }}`, `{{ basePath }}`, `{{ module }}`, `{{ controller }}`, `{{ service }}`, `{{ resource }}`, `{{ request }}``resource.stub`make-resource`{{ namespace }}`, `{{ resource }}``request.stub`make-request`{{ namespace }}`, `{{ request }}``routes-api.stub`make-routes`{{ basePath }}`, `{{ module }}`, `{{ controller }}`, `{{ resourceName }}``migration.stub`make-migration`{{ table }}`The package does not publish stubs by default. To customize generated files you would need to copy these stubs into your project and point the commands at your copies (or extend the commands). Namespaces and paths are derived from the module name and `config('orkestri.base_path')`.

---

Testing
-------

[](#testing)

The project uses [Orchestra Testbench](https://github.com/orchestral/testbench) and [Pest](https://pestphp.com/) for tests. Tests focus on the generator behaviour: correct directories, file paths, namespaces, stub content, config, and that existing modules/files are not overwritten.

```
composer install
./vendor/bin/pest
```

Test suites:

- **Feature** — `MakeModuleTest`, `MakeModelTest`, `MakeServiceTest` (and any other command tests). They assert structure, content, pluralization, custom `base_path`, and idempotency (e.g. second `make-module` for the same name exits with code 1).

---

License
-------

[](#license)

The MIT License (MIT). See the [LICENSE](LICENSE) file for details.

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance83

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

89d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f3d87bd6b95b6e64e7a8ac5a61c7db75fe15ebbe204a31bd7d485bb2623ce7a4?d=identicon)[lucaskaiut](/maintainers/lucaskaiut)

---

Top Contributors

[![lucaskaiut](https://avatars.githubusercontent.com/u/24759223?v=4)](https://github.com/lucaskaiut "lucaskaiut (6 commits)")

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/lucaskaiut-orkestri/health.svg)

```
[![Health](https://phpackages.com/badges/lucaskaiut-orkestri/health.svg)](https://phpackages.com/packages/lucaskaiut-orkestri)
```

###  Alternatives

[laravel/passport

Laravel Passport provides OAuth2 server support to Laravel.

3.4k85.0M532](/packages/laravel-passport)[nolimits4web/swiper

Most modern mobile touch slider and framework with hardware accelerated transitions

41.8k177.2k1](/packages/nolimits4web-swiper)[laravel/dusk

Laravel Dusk provides simple end-to-end testing and browser automation.

1.9k36.7M259](/packages/laravel-dusk)[laravel/prompts

Add beautiful and user-friendly forms to your command-line applications.

712181.8M596](/packages/laravel-prompts)[cakephp/chronos

A simple API extension for DateTime.

1.4k47.7M121](/packages/cakephp-chronos)[laravel/pail

Easily delve into your Laravel application's log files directly from the command line.

91545.3M590](/packages/laravel-pail)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
