Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Hmvc Laravel Package

zeus/hmvc

Zeus HMVC adds hierarchical model-view-controller support to Laravel, letting you group controllers, views, and routes into reusable, nestable modules. Build composable widgets and self-contained components without leaving Laravel's familiar conventions.

View on GitHub
Deep Wiki
Context7

Getting Started

zeus/hmvc is not a drop-in library you sprinkle into an existing Laravel app — it is a full HMVC application framework (routing, ORM, middleware, templating, request handling, optional Elasticsearch component) packaged as a Composer dependency. Treat adoption as "choosing a framework," not "adding a package."

Install and scaffold

composer require zeus/hmvc

Most frameworks of this shape ship a skeleton or a console binary. Check for one before hand-rolling bootstrap:

ls vendor/zeus/hmvc
ls vendor/zeus/hmvc/bin        # console entry point, if present
cat vendor/zeus/hmvc/composer.json | head -40   # PHP version + autoload map

Wire the public entry point (public/index.php) to the framework kernel if the package does not create it for you, and confirm the autoloader picks up your application namespace. Because the package is low-adoption (36 stars, 0 dependents), expect the README to be thinner than the code — the src/ tree and any examples/ or tests/ directory are your real documentation.

Where to look first, in this order

  1. composer.json — PHP constraint, PSR-4 roots, whether components are separate packages (zeus/orm, zeus/elasticsearch, …) or bundled.
  2. The module directory convention. HMVC frameworks almost always expect something like app/Modules/{Name}/{Controllers,Models,Views}. Confirm it before writing anything.
  3. The config directory — routing, database, middleware registration, and which optional components are enabled.
  4. The kernel/bootstrap class — this tells you the request lifecycle order (middleware → router → controller → view) and where you can hook in.

First use case: a self-contained module

The canonical first exercise is a "Hello" or "Posts" module that exercises controller + model + view in one folder:

// app/Modules/Blog/Controllers/PostsController.php
namespace App\Modules\Blog\Controllers;

class PostsController
{
    public function index()
    {
        $posts = \App\Modules\Blog\Models\Post::latest()->limit(10)->get();
        return view('blog::posts.index', ['posts' => $posts]);
    }
}

Register the route, hit it, and confirm the view resolution works before adding middleware or ORM relations. Getting module autoloading and view namespacing right on day one saves hours later.

Implementation Patterns

HMVC as the primary composition tool. The distinguishing feature versus plain MVC is that a controller can invoke another module's controller and receive its rendered output. This is how you build reusable widgets (a sidebar, a comment thread, a user badge) that own their own data access:

// inside a layout or another controller
$sidebar = \Zeus\Module::run('Blog/Sidebar/recent', ['limit' => 5]);

Use this deliberately: one level of nesting for widgets, rarely two. Every nested call pays controller-instantiation and view-render cost, and it hides an implicit dependency in your call graph.

Layering inside a module. Keep the same shape across every module so developers can move between them without re-orienting:

Modules/Blog/
  Controllers/    # thin: validate, delegate, render
  Models/         # ORM entities + query scopes
  Views/          # templates owned by this module
  Middleware/     # module-local filters
  routes.php      # module-local route table

Module-local route files keep a feature's surface area in one place and make deletion (the real test of modularity) trivial.

Middleware as a pipeline, configured globally and per-route. Register cross-cutting concerns (auth, CSRF, request logging, CORS) globally in config, and apply narrow concerns (rate limits, role checks) at the route or module level. Prefer one middleware per concern — chained "does everything" middleware is the usual rot point in small frameworks.

ORM usage. Work through model scopes rather than raw query builders in controllers, and keep eager-loading explicit. If the bundled ORM supports relations lazily but without a query log, wrap a debug listener early — N+1 problems in HMVC are worse because nested module calls multiply them.

Request object over superglobals. Take the framework's request instance as a parameter rather than reading $_POST/$_GET. That is what makes modules testable and what lets you swap in a synthetic request in a test.

Elasticsearch as an optional read path. Search is typically the first component people enable. The sane pattern is to treat the ORM as source of truth and Elasticsearch as a derived index maintained by model lifecycle hooks (create/update/delete) or a queued reindex job. Never let search be the only place a record exists.

Extension points to prefer. Custom components registered in config (a logger, a mailer, a storage driver) are the framework's stated design intent — "all of control on you include components." Write against small interfaces you define yourself (PostRepository, SearchIndex) and bind the framework's implementation behind them. That single practice is what makes a low-adoption framework survivable.

Gotchas and Tips

Maturity is the headline risk. 36 stars and zero dependents means no ecosystem, no Stack Overflow corpus, and no guarantee of backward compatibility between minor versions. Pin the exact version in composer.json, commit composer.lock, and read the diff before every upgrade. Budget for reading source when the docs run out — they will.

The description is the documentation. Marketing copy promising middleware, ORM, templating, and Elasticsearch does not tell you method signatures. Before committing to the framework, spend an hour in vendor/zeus/hmvc/src confirming each component actually exists and is wired up. Some listed features may be stubs or partially implemented.

Namespace and global collisions. Single-vendor frameworks sometimes ship global helper functions (view(), config(), run()) that collide with Laravel/Symfony packages you may add later. Grep the autoload files list in composer.json for globally loaded functions before adding any third-party dependency.

Nested module calls fail silently or loudly, inconsistently. Debug an HMVC call by invoking the target controller directly first — if it renders standalone but not through Module::run, the problem is module registration, view namespace, or a missing route, not your code.

Production caching. Module discovery, route tables, and config are typically compiled. In development you want those caches off so a new module is picked up immediately; in production you must turn them on or every request re-scans the filesystem. If you add a module and get a 404 in production but it works locally, this is why — clear the compiled cache.

Config load order. Environment variables, config files, and defaults usually resolve in a specific order. When a setting "doesn't take," check whether an earlier-loaded file is overwriting it. Log the resolved config once at boot during setup rather than guessing.

View namespacing is the #1 first-day frustration. blog::posts.index vs Modules/Blog/Views/posts/index.php — confirm the exact separator and path mapping in the template engine source before writing a dozen views against the wrong convention.

Testing. If the framework doesn't ship a testing harness, you can still unit-test models and services directly, and integration-test controllers by constructing the request object yourself. Abstract the framework behind interfaces (see above) so the majority of your tests never touch it — this is also your exit ramp if the project is abandoned.

Pin your PHP version and CI matrix. Small frameworks often use recent language features without documenting the minimum. Let CI catch the mismatch rather than your first deploy.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource