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

Foundation Laravel Package

cortex/foundation

Cortex Foundation supplies the shared core of the Cortex ecosystem: base contracts, service providers, and supporting utilities that modular Laravel applications build on. It standardises bootstrapping, configuration, and package integration so add-on packages stay consistent and lightweight.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: cortex/foundation (repo: rinvex/cortex-foundation-classic) is archived with 7 stars and 0 dependents. It is the legacy "classic" branch of Rinvex Cortex's modular architecture, aimed at Laravel 5.x-era apps. Treat it as legacy maintenance code, not a starting point for new projects. If you're here because an inherited codebase already uses it, the guide below is the shortest path to productivity.

The realistic setup:

composer require rinvex/cortex-foundation
php artisan vendor:publish --provider="Rinvex\Cortex\Providers\CortexServiceProvider"

(Laravel 5.5+ auto-discovers the provider; older apps need it in config/app.php.)

Where to look first, in order:

  1. config/cortex.php — the module registry and global switches.
  2. vendor/rinvex/cortex-foundation/src/Providers/ — the service providers that wire the framework extensions (routing, helpers, console).
  3. vendor/rinvex/cortex-foundation/src/Console/ — the scaffold commands; this is where day-to-day leverage lives.
  4. The Cortex facade / helper file, if present — global accessors used throughout dependent packages.

First real use case: scaffold a module and confirm it loads.

php artisan cortex:module Blog

This typically generates a self-contained module skeleton — composer.json, routes/, config/, src/Providers/, src/Http/Controllers/, src/Models/, database/migrations/, tests/ — and registers it in config/cortex.php. Then:

composer dump-autoload
php artisan config:clear
php artisan route:list | grep blog

If routes appear, the wiring works. If not, the module isn't discovered — see Gotchas.

Implementation Patterns

Treat every feature area as its own Composer package. That's the entire point of Cortex: modules are packages named rinvex/cortex-* (or cortex/* in older layouts), each with its own service provider, config, routes, migrations, and tests. The foundation package just boots them.

Extend the base module provider. Module providers inherit from a foundation-provided base class rather than Illuminate\Support\ServiceProvider, which is what gives you free route/config/migration/view registration:

namespace Cortex\Blog\Providers;

use Rinvex\Cortex\Support\ModuleServiceProvider; // confirm exact FQCN in vendor/

class BlogServiceProvider extends ModuleServiceProvider
{
    public function register(): void
    {
        parent::register();

        $this->app->bind(BlogRepositoryContract::class, BlogRepository::class);
    }

    public function boot(): void
    {
        parent::boot();

        // Module-specific: policies, event listeners, view composers
        Gate::policy(Post::class, PostPolicy::class);
    }
}

parent::register() / parent::boot() is what performs the convention-based loading (routes from routes/web.php and routes/api.php, config from config/blog.php, migrations from database/migrations/). Skip them and your module silently won't route or migrate.

Repository/contract binding is the idiomatic pattern. Cortex's own modules follow Contract → Repository → Model, with Eloquent isolated behind the interface. If you're extending existing Cortex modules (Attributes, Tenants, Authentication), match that structure — you'll be able to reuse their base classes and transformers.

Route registration via module convention, not app/Http/routes.php. Each module owns its routes. If you need conditional registration (e.g. API-only modules), do it inside the module provider:

public function boot(): void
{
    parent::boot();

    Route::middleware('api')
        ->prefix('api/v1')
        ->group(__DIR__.'/../../routes/api.php');
}

Cross-module communication via events, not direct calls. Because modules are Composer packages, they can (and should) be independently installable. Emit events (PostPublished, TenantSwitched) and let other modules listen. This keeps the dependency graph acyclic — the single most common failure mode in modular Laravel is modules referencing each other directly until composer install order matters.

Config merging overrides publishing. The foundation's base provider typically does mergeConfigFrom(__DIR__.'/../config/blog.php', 'blog'). Override per-environment in config/blog.php (app-level), not in the package. That way vendored modules stay updateable.

Middleware and auth guards are per-module. With cortex/foundation, modules like cortex-authentication register their own guards and middleware aliases. If you're building an admin module, register its guard in your module provider rather than mutating config/auth.php.

Testing pattern: each module ships its own phpunit.xml and tests against the module in isolation (via orchestra/testbench or a minimal Laravel bootstrap). The foundation package itself is thin — don't try to unit-test it, integration-test your modules instead.

Gotchas and Tips

Archived = no patches. Assume no Laravel 9/10/11 support. The -classic suffix exists precisely because the author forked forward and left this behind. Before adopting, check composer.json's illuminate/* constraints against your Laravel version — the install will silently resolve to something ancient or explode, and either outcome is bad. If you're on Laravel ≥ 6, this package is a hard no; use nwidart/laravel-modules instead.

Module discovery is the #1 debugging surface. If a module's routes/commands don't show up, the checklist is: (1) composer dump-autoload after scaffolding; (2) php artisan config:clear (the module list is cached); (3) module is present in config/cortex.php; (4) provider is registered; (5) provider calls parent::register(). Work the list in that order — 90% of "module isn't loading" issues are steps 1–2.

Config caching breaks module overrides. php artisan config:cache serializes the merged config. If you add a module after caching, it won't appear until you clear. In CI, always run config:clear before config:cache.

Scaffold output is a template, not a contract. The cortex:module command generates a starter skeleton. Rename/delete freely — foundation looks up conventions (routes path, config path), not class names. But if you move the module's directory, update composer.json's psr-4 block and re-dump autoload.

Migration ordering across modules is manual. Modules each own migrations, and php artisan migrate runs them in discovery order. Cross-module foreign keys (e.g. posts.tenant_id referencing a tenant table owned by cortex-tenants) will break if discovery order shifts. Mitigation: put cross-module FKs in a separate "glue" migration in your app, or make them nullable without the constraint.

Don't mutate vendor modules. Fork, or copy the module into your app/-adjacent modules/ directory and re-register. Because modules are Composer packages, composer update will obliterate in-vendor edits.

Extensions points to lean on: (1) the base ModuleServiceProvider — override register() / boot() hooks if it has protected methods for config/routes/views (many Cortex versions do); (2) the Cortex facade for runtime module state; (3) events emitted during module boot. These are the stable surface — the internal classes are not.

Lock the version. With no maintainer, composer require rinvex/cortex-foundation:* will one day pull something broken or yanked. Pin to an exact version in composer.json and add a composer.lock to version control. Consider a private Satis/Packagist mirror if you can't tolerate the package disappearing from Packagist.

Plan an exit. Because dependents are zero and the repo is archived, the honest long-term move for any production system on this is a migration to nwidart/laravel-modules (actively maintained, same mental model: modules-as-packages, per-module routes/config/migrations) or to Laravel's built-in app/Domain/* conventions if you don't need true package isolation. The module boundaries you define here will port over largely intact — that's the one silver lining.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager