PHPackages                             opscale-co/nova-package-tools - 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. opscale-co/nova-package-tools

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

opscale-co/nova-package-tools
=============================

Tools for creating Nova packages

1.1.0(2mo ago)01.0k↑53.3%9MITShellPHP ^8.2CI passing

Since Sep 19Pushed 2mo agoCompare

[ Source](https://github.com/opscale-co/nova-package-tools)[ Packagist](https://packagist.org/packages/opscale-co/nova-package-tools)[ Docs](https://github.com/opscale-co/nova-package-tools)[ RSS](/packages/opscale-co-nova-package-tools/feed)WikiDiscussions main Synced yesterday

READMEChangelog (3)Dependencies (26)Versions (4)Used By (9)

Support us
----------

[](#support-us)

At Opscale, we’re passionate about contributing to the open-source community by providing solutions that help businesses scale efficiently. If you’ve found our tools helpful, here are a few ways you can show your support:

⭐ **Star this repository** to help others discover our work and be part of our growing community. Every star makes a difference!

💬 **Share your experience** by leaving a review on [Trustpilot](https://www.trustpilot.com/review/opscale.co) or sharing your thoughts on social media. Your feedback helps us improve and grow!

📧 **Send us feedback** on what we can improve at . We value your input to make our tools even better for everyone.

🙏 **Get involved** by actively contributing to our open-source repositories. Your participation benefits the entire community and helps push the boundaries of what’s possible.

💼 **Hire us** if you need custom dashboards, admin panels, internal tools or MVPs tailored to your business. With our expertise, we can help you systematize operations or enhance your existing product. Contact us at  to discuss your project needs.

Thanks for helping Opscale continue to scale! 🚀

Description
-----------

[](#description)

This package extends [Spatie's Laravel Package Tools](https://github.com/spatie/laravel-package-tools) to provide Nova-specific functionality for package development. It inherits all the features from the base package while adding support for Nova resources, assets, routes, event listeners and `Nova::serving` callbacks.

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

[](#installation)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d6ff509161b0c538bc3a2869849d2d58747c0441ca96ccac2da51f8cb1853a4e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f707363616c652d636f2f6e6f76612d7061636b6167652d746f6f6c732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/opscale-co/nova-package-tools)

You can install the package in to a Laravel app that uses [Nova](https://nova.laravel.com) via composer:

```
composer require opscale-co/nova-package-tools
```

Usage
-----

[](#usage)

### Getting Started

[](#getting-started)

In your Nova package, you should let your service provider extend `Opscale\NovaPackageTools\NovaPackageServiceProvider`:

```
use Opscale\NovaPackageTools\NovaPackageServiceProvider;
use Spatie\LaravelPackageTools\Package;

class YourNovaPackageServiceProvider extends NovaPackageServiceProvider
{
    public function configurePackage(Package $package): void
    {
        $package
            ->name('your-nova-package')
            ->hasConfigFile()
            ->hasViews()
            ->hasMigration('create_your_package_tables')
            ->hasCommand(YourPackageCommand::class)
            // Nova-specific features are now directly available
            ->hasResource(YourResource::class)
            ->hasResources([
                UserResource::class,
                PostResource::class,
            ])
            ->hasNovaAssets('your-nova-package', __DIR__.'/../dist')
            ->hasNovaApiRoute(__DIR__.'/../routes/api.php', 'your-nova-package')
            ->hasNovaPageRoute(__DIR__.'/../routes/nova.php', '/your-nova-package')
            ->hasListener(SomeEvent::class, SomeListener::class)
            ->servingNova(function () {
                // Register fields, tools, dashboards, etc.
            });
    }
}
```

### Nova Resources

[](#nova-resources)

The main addition this package provides is the ability to register Nova resources with your package.

#### Registering a Single Resource

[](#registering-a-single-resource)

You can register a single Nova resource using the `hasResource` method:

```
use App\Nova\User;

$package
    ->name('your-nova-package')
    ->hasResource(User::class);
```

#### Registering Multiple Resources

[](#registering-multiple-resources)

If your package provides multiple Nova resources, you can register them all at once using `hasResources`:

```
use App\Nova\User;
use App\Nova\Post;
use App\Nova\Comment;

$package
    ->name('your-nova-package')
    ->hasResources([
        User::class,
        Post::class,
        Comment::class,
    ]);
```

You can also pass multiple resources as separate arguments:

```
$package
    ->name('your-nova-package')
    ->hasResources(User::class, Post::class, Comment::class);
```

### Nova Assets

[](#nova-assets)

Register the JavaScript and CSS assets that ship with your Nova tool or field. Assets are published automatically and registered with `Nova::script()` / `Nova::style()` inside `Nova::serving()`.

```
$package
    ->name('your-nova-package')
    // Register a single script or style:
    ->hasNovaScript('your-nova-package', __DIR__.'/../dist/js/tool.js')
    ->hasNovaStyle('your-nova-package', __DIR__.'/../dist/css/tool.css');
```

For the typical Nova layout (a `dist/` directory containing `js/` and `css/` folders), use `hasNovaAssets()` to register both at once:

```
$package
    ->name('your-nova-package')
    // For a Nova tool (dist/js/tool.js + dist/css/tool.css):
    ->hasNovaAssets('your-nova-package', __DIR__.'/../dist', 'tool');

$package
    ->name('your-nova-field')
    // For a Nova field (dist/js/field.js + dist/css/field.css):
    ->hasNovaAssets('your-nova-field', __DIR__.'/../dist', 'field');
```

### Nova Routes

[](#nova-routes)

Register route files that should be loaded with Nova's middleware stack.

Use `hasNovaApiRoute()` for XHR endpoints called from your Nova tool's Vue components — these are mounted under `nova-vendor/{prefix}`:

```
$package
    ->name('your-nova-package')
    ->hasNovaApiRoute(__DIR__.'/../routes/api.php', 'your-nova-package');
```

Use `hasNovaPageRoute()` for full Nova pages that should render with the standard Nova layout:

```
$package
    ->name('your-nova-package')
    ->hasNovaPageRoute(__DIR__.'/../routes/nova.php', '/your-nova-package');
```

Both methods accept an optional middleware list as the third argument. When omitted, sensible Nova defaults are applied (`['nova', Authorize::class]` for API routes and `['nova', Authenticate::class, Authorize::class]` for page routes).

```
$package
    ->hasNovaApiRoute(
        __DIR__.'/../routes/api.php',
        'your-nova-package',
        ['nova', Authorize::class, 'custom-middleware']
    );
```

### Event Listeners

[](#event-listeners)

Register event listeners for your package without having to wire them up manually in a service provider.

```
use App\Events\OrderShipped;
use App\Listeners\SendShipmentNotification;

$package
    ->name('your-nova-package')
    // Register a single event listener:
    ->hasListener(OrderShipped::class, SendShipmentNotification::class);
```

Listeners may be class names, `[Class::class, 'method']` arrays, or closures. You can also register multiple listeners at once:

```
$package
    ->name('your-nova-package')
    ->hasListeners([
        OrderShipped::class => SendShipmentNotification::class,
        OrderCancelled::class => [NotifyTeam::class, 'handle'],
    ]);
```

### Serving Callbacks

[](#serving-callbacks)

Register callbacks that should run inside `Nova::serving()`. This is the right place to register fields, tools, dashboards, or any other Nova-aware code that needs Nova to be booted first.

```
use Laravel\Nova\Nova;

$package
    ->name('your-nova-package')
    ->servingNova(function () {
        Nova::tools([
            new YourPackageTool(),
        ]);
    });
```

You can call `servingNova()` multiple times to register additional callbacks.

Testing
-------

[](#testing)

```
npm run test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/opscale-co/.github/blob/main/CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Opscale](https://github.com/opscale-co)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance87

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81.3% 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 ~112 days

Total

3

Last Release

62d ago

PHP version history (2 changes)1.0.0PHP ^8.0

1.0.1PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3722594?v=4)[opscale](/maintainers/opscale)[@opscale](https://github.com/opscale)

---

Top Contributors

[![opscale-development](https://avatars.githubusercontent.com/u/181295122?v=4)](https://github.com/opscale-development "opscale-development (13 commits)")[![semantic-release-bot](https://avatars.githubusercontent.com/u/32174276?v=4)](https://github.com/semantic-release-bot "semantic-release-bot (3 commits)")

---

Tags

opscalenova-package-tools

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

### Embed Badge

![Health badge](/badges/opscale-co-nova-package-tools/health.svg)

```
[![Health](https://phpackages.com/badges/opscale-co-nova-package-tools/health.svg)](https://phpackages.com/packages/opscale-co-nova-package-tools)
```

###  Alternatives

[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M47](/packages/spatie-laravel-pdf)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

329530.5k29](/packages/codewithdennis-filament-select-tree)[worksome/exchange

Check Exchange Rates for any currency in Laravel.

124603.0k](/packages/worksome-exchange)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.6k](/packages/rawilk-profile-filament-plugin)

PHPackages © 2026

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