PHPackages                             baconfy/core - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. baconfy/core

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

baconfy/core
============

Core module system for Baconfy.

v0.1.1(1mo ago)02MITPHPPHP ^8.3CI passing

Since Jun 12Pushed 1mo agoCompare

[ Source](https://github.com/baconfy/core)[ Packagist](https://packagist.org/packages/baconfy/core)[ RSS](/packages/baconfy-core/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (13)Versions (4)Used By (0)

 [![Core](https://raw.githubusercontent.com/baconfy/core/main/.docs/presentation.jpg)](https://raw.githubusercontent.com/baconfy/core/main/.docs/presentation.jpg)

[![Tests](https://github.com/baconfy/core/actions/workflows/tests.yml/badge.svg)](https://github.com/baconfy/core/actions/workflows/tests.yml)[![Latest Version](https://camo.githubusercontent.com/d7cccfd29dd9f1622bc6f7ea825d22063198781ac77726525ed3f6c81a5400bb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6261636f6e66792f636f72652e737667)](https://packagist.org/packages/baconfy/core)[![License](https://camo.githubusercontent.com/fb108b097cab05a3be43beb90a4ef9d72c83cc87df741154188dfcbba411c0ba/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6261636f6e66792f636f72652e737667)](https://packagist.org/packages/baconfy/core)[![Total Downloads](https://camo.githubusercontent.com/f30c3aae1df56b9a032e903c999240f8ddd0baa14ac3ad364e43fe2daf1d9766/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6261636f6e66792f636f72652e737667)](https://packagist.org/packages/baconfy/core)[![PHP Version](https://camo.githubusercontent.com/f6f0394777103e87c2c57d8568ad29175df30d5c615ea63fa121bed69ec1a376/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6261636f6e66792f636f72652e737667)](https://packagist.org/packages/baconfy/core)

The module system at the heart of the Baconfy ecosystem. It lets Composer packages register themselves as application modules — with a name, label, icon, entry route, navigation tree and visibility rules — so the application shell can discover and render them with zero configuration.

This package is **pure PHP** and has no opinion about your frontend. It is consumed by [`baconfy/interface`](https://github.com/baconfy/interface), which turns registered modules into a launcher and sidebar.

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

[](#requirements)

- PHP 8.3+
- Laravel 11, 12 or 13

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

[](#installation)

```
composer require baconfy/core
```

The service provider is auto-discovered. A `ModuleRegistry` singleton becomes available in the container.

Creating a module
-----------------

[](#creating-a-module)

A module is a regular Laravel package whose service provider extends `ModuleProvider`. Three methods are required:

```
use Baconfy\Core\ModuleProvider;

class NotesServiceProvider extends ModuleProvider
{
    public function name(): string
    {
        return 'notes';
    }

    public function label(): string
    {
        return __('Notes');
    }

    public function icon(): string
    {
        return 'notebook-pen';
    }
}
```

That's it. The module is registered automatically when the provider boots.

### Your `boot()` stays yours

[](#your-boot-stays-yours)

`ModuleProvider` does **not** touch the `boot()` method — registration happens through a provider `booting` callback. Write your boot exactly the way you would in any Laravel package:

```
public function boot(): void
{
    Route::middleware('web')
        ->prefix($this->name())
        ->name($this->name().'.')
        ->group(fn () => $this->loadRoutesFrom(__DIR__.'/../routes/web.php'));

    $this->loadMigrationsFrom(__DIR__.'/../database/migrations');
}
```

Conventions
-----------

[](#conventions)

The module **name** is the universal key. By convention it is also:

ConcernConventionOverrideEntry route`{name}.index``routeName(): ?string`Visibility gategate named `{name}`, if defined`can(): ?string`Launcher position`order = 100``order(): int`JS page namespace`extra.baconfy.module` in composer.json— (must match `name()`)### Visibility

[](#visibility)

Three rules, checked in order:

1. **Explicit `can()`** — the module is visible only to users allowed by that gate.
2. **Convention gate** — if a gate named after the module exists (`Gate::define('notes', ...)`), it decides. The application controls access without the module knowing.
3. **Otherwise** — the module is public, including for guests.

### Manifest validation

[](#manifest-validation)

If the package's `composer.json` declares a Baconfy manifest, the module key must match the provider's `name()`:

```
{
    "extra": {
        "baconfy": {
            "module": "notes"
        }
    }
}
```

A mismatch throws `ManifestMismatchException` at boot — configuration errors die early and loudly. The manifest is optional: headless modules (no frontend pages) don't need one.

Navigation
----------

[](#navigation)

Modules may expose a navigation tree by overriding `navigation()`:

```
use Baconfy\Core\Navigation;

public function navigation(): ?iterable
{
    return [
        Navigation::make(__('All notes'))->icon('list')->route('notes.index'),

        Navigation::make(__('Archive'))->children(
            Note::distinctYears()->map(
                fn (int $year) => Navigation::make((string) $year)
                    ->route('notes.archive', ['year' => $year]),
            ),
        ),

        Navigation::make(__('Settings'))
            ->route('notes.settings')
            ->can('notes.settings'),
    ];
}
```

- Trees nest to any depth through `children()` (accepts arrays or Collections).
- Items with `can()` are pruned for users who fail the gate — and for guests.
- Route-less items act as group headings; a group whose children were all pruned disappears with them.
- Returning `null` (the default) means the module has no sidebar navigation at all.

Lazy by design
--------------

[](#lazy-by-design)

`label()` and `navigation()` are **never called during boot**. They are wrapped in closures and evaluated only at serialization time, per request. This means:

- labels translate to the locale of the current request, not the boot locale;
- navigation may safely query the database without taxing every request;
- long-running runtimes (Octane) never freeze stale values.

Consuming the registry
----------------------

[](#consuming-the-registry)

```
use Baconfy\Core\ModuleRegistry;

$registry = app(ModuleRegistry::class);

$registry->all();                       // every module, sorted by order then name
$registry->visibleFor($user);           // only what this user may see
$registry->get('notes');                // a single module
```

Sharing modules with an Inertia frontend is a one-liner:

```
Inertia::share('baconfy.modules', fn () => app(ModuleRegistry::class)
    ->visibleFor(auth()->user())
    ->map->toArray(auth()->user()));
```

Each module serializes to:

```
{
    "name": "notes",
    "label": "Notes",
    "icon": "notebook-pen",
    "url": "https://app.test/notes",
    "order": 100,
    "navigation": [
        { "label": "All notes", "icon": "list", "url": "https://app.test/notes", "children": [] }
    ]
}
```

`url` is `null` when the entry route doesn't exist; `navigation` is `null` when the module defines none.

Testing
-------

[](#testing)

```
composer test   # pest
composer lint   # pint + phpstan
```

The suite runs against PHP 8.3/8.4/8.5 × Laravel 11/12/13 in CI.

License
-------

[](#license)

MIT.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance91

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

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

Every ~0 days

Total

2

Last Release

45d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7077461?v=4)[Renato Dehnhardt](/maintainers/rdehnhardt)[@rdehnhardt](https://github.com/rdehnhardt)

---

Top Contributors

[![rdehnhardt](https://avatars.githubusercontent.com/u/7077461?v=4)](https://github.com/rdehnhardt "rdehnhardt (11 commits)")

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/baconfy-core/health.svg)

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

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M348](/packages/psalm-plugin-laravel)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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