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

Laravel Moonlight Laravel Package

titasgailius/laravel-moonlight

Moonlight is a Laravel package for quickly building admin panels and CRUD interfaces around your Eloquent models. Define resources once and get searchable listings, forms, filters, and actions without writing repetitive controller or view code.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a scaffolding preset, not a runtime library — the whole point is to run it once and then remove it.

composer require titasgailius/laravel-moonlight --dev
php artisan moonlight:install
npm install && npm run dev

Start on a fresh Laravel app (or commit first — see Gotchas). The installer writes Inertia + Vue + Tailwind scaffolding over your app: resources/js/app.js, resources/js/Pages/, resources/js/Layouts/, auth controllers, routes/web.php, webpack.mix.js, and a Tailwind config.

First place to look: the generated resources/js/Pages/ directory and routes/web.php. The first real use case is replacing the default welcome.blade.php with an Inertia-rendered SPA shell and getting the generated login/register/forgot-password flow working end-to-end (/login, /register, /dashboard). Once that round-trips through Inertia, you have a working template to build features on.

Then immediately:

composer remove titasgailius/laravel-moonlight --dev

It has no runtime role after install. Keeping it as a dependency only confuses future readers of composer.json.

Implementation Patterns

Once installed, you're writing ordinary Inertia + Vue 2 code — Moonlight just gave you the starting files.

Controller → page: use the generated controllers as templates and follow the same shape:

return Inertia::render('Dashboard/Index', ['stats' => $stats]);

The string must map to resources/js/Pages/Dashboard/Index.vue.

Forms: use useForm from @inertiajs/inertia-vue, not axios. The generated auth pages show the pattern:

const form = useForm({ email: '', password: '' });
form.post(route('login'));

This gives you form.errors, form.processing, and automatic error binding for validation responses.

Shared props: register global data (authenticated user, flash messages, app name) in the generated HandleInertiaRequests middleware via share(). Read them in Vue via this.$page.props.auth.user or the usePage() helper. This is the standard place to hang a toast/flash component.

Layouts: use the persistent layout pattern the generated pages use — assign layout: AppLayout on the page component rather than wrapping with <app-layout> in the template. Persistent layouts preserve component state (scroll, form drafts) across visits.

Navigation: use <inertia-link :href="route('dashboard')"> (Vue 2 component) instead of <a> so you get SPA transitions. Route names come from Laravel, same as Blade.

Auth flow: the installer wires login, register, password reset and email verification against Laravel's Auth guards. Extend the generated controllers rather than replacing them — the redirects and Auth::attempt handling are already correct.

Styling: extend tailwind.config.js with your design tokens and reuse the generated button/input/card components in resources/js/Components/. That's the fastest path to a consistent UI.

Gotchas and Tips

Vue 2 and webpack-mix — this is a 2023 snapshot. Vue 2 reached end-of-life in December 2023 and the preset still uses webpack.mix.js rather than Vite. On Laravel 9+ you'll be fighting the framework default. If you're starting a new project, prefer Laravel Breeze (Vue + Inertia + Tailwind) — it's first-party, maintained, and targets Vue 3 / Inertia v1 / Vite. Moonlight makes sense mainly for resurrecting or matching an older codebase.

Commit before running the installer. moonlight:install overwrites routes/web.php, app.js, package.json, and adds many files. Without a clean commit you cannot cleanly diff what it changed or revert.

Don't layer it on Breeze/Jetstream/Laravel UI. Duplicate auth controllers and route definitions will collide. Install on a fresh skeleton only.

npm install is not run for you. The command scaffolds files, then stops. Run npm install && npm run dev (or npm run watch) manually — the "nothing renders" symptom is almost always a forgotten build.

Inertia page names are path-sensitive. Inertia::render('Auth/Login') requires exactly resources/js/Pages/Auth/Login.vue. A mismatch produces a blank page with a console error rather than a PHP exception — check the browser console and network tab first when debugging.

No update path. Once installed, the code is yours. Upstream bug fixes and dependency bumps won't reach you. Treat the generated files as a fork, not a managed dependency.

Extension points: resources/js/app.js for global Vue plugin registration (e.g. Ziggy, Vuex/Pinia), and HandleInertiaRequests's share() for cross-cutting props. Both are safe places to add behavior without touching the auth scaffolding.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource