christyoga123 / vuelament
Lightning-fast Admin Dashboard & CRUD Generator for Laravel (VILT Stack)
Requires
- php: ^8.2
- inertiajs/inertia-laravel: ^2.0
- laravel/framework: ^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0
- phpunit/phpunit: ^11.0
Suggests
- spatie/laravel-permission: Required for role & permission management (^7.0)
This package is auto-updated.
Last update: 2026-03-15 09:20:05 UTC
README
π Vuelament
A lightning-fast, lightweight, and modern Admin Dashboard & CRUD Generator for Laravel.
Built on the VILT stack (Vue 3, Inertia.js, Laravel, Tailwind CSS) and powered by Shadcn Vue for a gorgeous UI.
β¨ Features
- Ultra Lightweight: Minimal dependencies, split code-chunking, and no bloat.
- Beautiful UI: Uses Tailwind CSS v4 and Shadcn-Vue for a premium, accessible, and easily customizable design.
- VILT Stack: Seamless SPA experience powered by Laravel, Inertia, Vue 3, and Tailwind.
- Filament-Inspired Architecture: Panel-first, module-based structure with page classes, header actions, and service-based action handling.
- No Per-Model Controllers: Generic
ResourceRouteControllerhandles all CRUD routing automatically β zero boilerplate. - Complete Form Builder: Supports Rich Editor (Vue Quill), Date/Time Pickers (VueDatePicker), File Uploads, Selects, Toggles, Checkboxes, Radios, and responsive Grid Layouts.
- Client-Side Form Reactivity: Show/hide, enable/disable, and change required state of fields instantly without server requests.
- Robust Table Builder: Supports filtering, search, pagination, bulk actions, column toggling, and rich column types (Text, Badge, Toggle, Checkbox, Image, Icon).
- Service-Based Actions: Business logic lives in dedicated Service classes β testable, reusable, and separated from framework concerns.
- Dynamic Modals: Conditional Action dialogs, flexible modal widths, click-away handling, and dangerous action confirmations.
- Multi-Panel Support: Run multiple isolated admin panels (Admin, Sales, etc.) with zero conflict.
π¦ Requirements
- PHP 8.2+
- Laravel 11.x / 12.x
- Node.js 18+ & NPM
π οΈ Installation (Step-by-Step Manual)
Due to frequent issues with automated Shadcn-Vue installations and Tailwind CSS versions, we highly recommend setting up Vuelament and Shadcn-Vue manually following these best practices. Let's build your panel step-by-step!
1. Install via Composer
Gunakan constraint versi stabil (bukan dev-main) agar dapat update yang ter-tag (mis. 1.7.1):
composer require christyoga123/vuelament:^1.7
Atau di composer.json:
"christyoga123/vuelament": "^1.7"
Lalu composer update christyoga123/vuelament akan mengambil rilis terbaru (mis. 1.7.1). Hindari dev-main di production.
2. Scaffold Configuration & Base Layouts
Run the install command to publish config & Blade, generate the panel provider, and scaffold Vite/Inertia. Vue/JS assets (Pages, Layouts, components) are not copied β they stay in vendor/christyoga123/vuelament/resources/js, so when you run composer update christyoga123/vuelament the UI (forms, tables, etc.) updates automatically.
php artisan vuelament:install
To override or customize specific Vue files, copy them into your app first:
php artisan vendor:publish --tag=vuelament-views
Then edit the copies in resources/js/Pages/Vuelament, resources/js/Layouts, or resources/js/components/vuelament as needed.
3. Install NPM Dependencies
Install Inertia, Vue, Tailwind plugins, and other essential Vuelament dependencies:
npm install @inertiajs/vue3 @vitejs/plugin-vue @vueuse/core @vueup/vue-quill @vuepic/vue-datepicker lucide-vue-next vue-sonner reka-ui class-variance-authority clsx tailwind-merge tw-animate-css npm install -D typescript vue-tsc
4. Setup Shadcn-Vue (Manual Initialization)
Run the Shadcn-Vue initialization wizard:
npx shadcn-vue@latest init
Choose your preferred settings. Make sure to match this components.json layout, specifically setting "typescript": false and your aliases to @/components and @/lib/utils:
{
"$schema": "https://shadcn-vue.com/schema.json",
"style": "new-york",
"typescript": false,
"tailwind": {
"config": "",
"css": "resources/css/app.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"composables": "@/composables"
}
}
5. Install Shadcn-Vue Required Components
Vuelament relies on several key components. Install them in one go:
npx shadcn-vue@latest add alert-dialog avatar breadcrumb button card checkbox dialog dropdown-menu input label pagination popover radio-group scroll-area select separator sheet sidebar skeleton sonner switch table textarea tooltip
Tip: If you encounter an error trying to pull the sidebar component (due to strict typescript rules), temporarily change "typescript": true inside components.json, run the add command again, and revert back to false.
6. Run Migrations & Create Admin
Finally, finish the setup by running your migrations, creating an initial user, and starting your dev server:
php artisan migrate php artisan vuelament:user npm run dev php artisan serve
Visit http://localhost:8000/admin/login to access your dashboard!
Upgrading: If you see "Failed to resolve import @vuelament/AppWrapper.vue", your vite.config.js is missing the @vuelament alias β run php artisan vuelament:install once. If you see "Failed to resolve import @/lib/utils", run install to create resources/js/lib/utils.js. If the sidebar overlaps the main content (layout broken), Tailwind isnβt scanning the vendor Vue files β run php artisan vuelament:install to add @source "../../vendor/christyoga123/vuelament/resources/js/**/*.vue" to resources/css/app.css so classes like lg:pl-64 are generated. If you previously published Vue files, remove them from resources/js so the app uses the copy in vendor.
Updating Shadcn-Vue components
Shadcn-Vue components live in your app (resources/js/components/ui/), so they donβt update automatically. To pull the latest version of a component from the registry, run:
npx shadcn-vue@latest add <component-name>
Example: npx shadcn-vue@latest add button sonner. If the file already exists, the CLI will usually ask whether to overwrite. Choose overwrite to get the new code β if youβve customized that file, merge your changes manually or keep a backup first.
π Architecture β Panel-First, Module-Based
app/Vuelament/{Panel}/{Model}/
βββ Resources/ β CRUD page classes (like Filament)
β βββ List{Model}s.php β getHeaderActions(): [CreateAction::make()]
β βββ Create{Model}.php β getHeaderActions(), getFormActions()
β βββ Edit{Model}.php β getHeaderActions(), getFormActions()
β
βββ Pages/ β Custom pages (non-CRUD)
β
βββ Services/ β Business logic (service-based actions)
β βββ {Model}Service.php
β
βββ Widgets/ β Dashboard widgets
β
βββ {Model}Resource.php β Form schema, table schema, getPages()
No per-model controller needed! The framework's generic
ResourceRouteControllerhandles all CRUD routing automatically. You only need Resource + Page classes + Services.
π§© Artisan Commands
Generate a Resource (full module)
# Multi-page mode (default) β generates List, Create, Edit pages php artisan vuelament:resource Product --panel=Admin # Single mode β modal-based create/edit (ManageProducts) php artisan vuelament:resource Product --panel=Admin --simple # Auto-generate form/table from database columns php artisan vuelament:resource Product --panel=Admin --generate
This generates the full module structure:
app/Vuelament/Admin/Product/
βββ Resources/
β βββ ListProducts.php β with CreateAction in getHeaderActions()
β βββ CreateProduct.php
β βββ EditProduct.php
βββ Pages/
βββ Services/
β βββ ProductService.php
βββ Widgets/
βββ ProductResource.php β with getPages() referencing page classes
Generate a Service
# Basic β creates ProductService in the Product module php artisan vuelament:service Product --panel=Admin # With explicit resource module php artisan vuelament:service Payment --panel=Admin --resource=Order
Generate a Custom Page
# Standalone page php artisan vuelament:page Analytics --panel=Admin # Page attached to a resource php artisan vuelament:page Report --panel=Admin --resource=User
Generate a Panel
php artisan vuelament:panel Sales --id=sales
Create Admin User
php artisan vuelament:user
π Usage Guide
Page Classes β Like Filament
Page classes define page-level actions via getHeaderActions(). This is identical to Filament's pattern.
// app/Vuelament/Admin/User/Resources/ListUsers.php use ChristYoga123\Vuelament\Core\Pages\ListRecords; use ChristYoga123\Vuelament\Components\Actions\CreateAction; class ListUsers extends ListRecords { protected static ?string $resource = UserResource::class; public static function getHeaderActions(): array { return [ CreateAction::make(), // ExportAction::make(), // ImportAction::make(), ]; } }
Resource Registration β getPages()
Resources register their CRUD page classes and custom pages in getPages():
public static function getPages(): array { return [ // CRUD page classes β framework reads getHeaderActions() from these 'index' => Resources\ListUsers::class, 'create' => Resources\CreateUser::class, 'edit' => Resources\EditUser::class, // Custom pages 'report' => Pages\ReportPage::route('/{record}/report'), ]; }
Table Schema β Row-Level Actions Only
Table schemas contain only row-level inline actions. Page-level actions (like "Create") belong in getHeaderActions() on the page class.
public static function tableSchema(): PageSchema { return PageSchema::make() ->components([ Table::make() ->query(fn() => User::query()->latest()) ->columns([ TextColumn::make('name')->searchable()->sortable(), TextColumn::make('email')->sortable()->searchable(), ToggleColumn::make('is_active')->label('Active'), ]) ->actions([ // β Row-level actions (inline in table) Action::make('deactivate') ->icon('user-x') ->color('warning') ->requiresConfirmation('Deactivate User', 'Are you sure?') ->action([UserService::class, 'deactivate']), EditAction::make(), DeleteAction::make(), ]) ->bulkActions([ ActionGroup::make('Bulk Actions') ->icon('list') ->actions([ DeleteBulkAction::make(), RestoreBulkAction::make(), ]), ]) ->filters([ TrashFilter::make(), ]) ->searchable() ->paginated() ->selectable(), ]); }
Defining Forms
use ChristYoga123\Vuelament\Components\Layout\Grid; use ChristYoga123\Vuelament\Components\Layout\Section; use ChristYoga123\Vuelament\Components\Form\TextInput; use ChristYoga123\Vuelament\Components\Form\Toggle; public static function formSchema(): PageSchema { return PageSchema::make() ->components([ Section::make('General Information') ->components([ Grid::make(2)->components([ TextInput::make('name')->required()->uniqueIgnoreRecord(), TextInput::make('email')->email()->required()->uniqueIgnoreRecord(), ]), Toggle::make('is_active') ->label('Status Active') ->hint('Turn off to prevent user login.'), TextInput::make('password') ->password() ->revealable() ->dehydrateStateUsing(fn (string $state): string => Hash::make($state)) ->saved(fn (?string $state): bool => filled($state)) ->required(fn (string $operation): bool => $operation === 'create'), ]) ]); }
Available Form Controls
TextInputβ text, email, password, number, with prefix/suffix and revealable supportTextareaβ multi-line text inputRichEditorβ Rich text editor (powered by VueQuill)DatePicker,TimePicker,DateRangePickerβ Date/time selection (powered by VuePic)Selectβ Dropdown selectionCheckboxβ Single or multiple checkbox groupRadioβ Radio button group with horizontal/vertical layoutToggleβ Switch toggle (powered by Shadcn Switch)FileInputβ File upload with drag & drop, preview, and reorder supportRepeaterβ Dynamic repeatable field groups
β‘ Service-Based Actions
Unlike Filament (where actions use Livewire Closures), Vuelament uses dedicated Service classes for business logic. This makes actions testable, reusable, and framework-agnostic.
Flow
Resource β defines actions with form + service callable
β
Action β captures form data, resolves service from container
β
Service β executes business logic (pure PHP, testable)
β
Database β Eloquent operations
Action in Resource
Action::make('deactivate') ->icon('user-x') ->color('warning') ->requiresConfirmation('Deactivate User', 'Are you sure?') ->action([UserService::class, 'deactivate'])
Service Class
// app/Vuelament/Admin/User/Services/UserService.php class UserService { public function deactivate(User $user, array $data = []): void { $user->update(['is_active' => false]); } }
How It Works
The framework resolves the service instance from the container and injects dependencies:
$instance = app(UserService::class); app()->call([$instance, 'deactivate'], [ 'user' => $record, // injected by lowercase model basename 'record' => $record, // also available as generic 'record' 'data' => $formData, // form data from modal ]);
Actions with Forms
Action::make('assign_role') ->icon('shield') ->color('success') ->form([ Select::make('role')->options([ 'admin' => 'Admin', 'editor' => 'Editor', ])->required(), ]) ->action([UserService::class, 'assignRole'])
π― Form Reactivity (Client-Side)
Vuelament evaluates form visibility, disabled, and required states entirely on the client β no server requests needed.
βοΈ Vuelament vs Filament
| Interaction | Filament (Livewire) | Vuelament (Vue 3 + Inertia) |
|---|---|---|
| Toggle field to show another | π Network request, re-renders component | β‘ Instant. JavaScript only |
| Change required state based on selection | π Requires network request | β‘ Instant. No server overhead |
| Simple validation visibility | π Network round-trip, can feel sluggish | β‘ Instant. Zero latency |
Toggle::make('is_active')->label('Active Status'), // Shows INSTANTLY when is_active is toggled on (no server request!) TextInput::make('activation_code') ->visibleWhen('is_active', true) ->requiredWhen('is_active', true), Select::make('type')->options([ 'standard' => 'Standard', 'premium' => 'Premium', ]), // Shows only when type = 'premium' TextInput::make('premium_code') ->visibleWhen('type', 'premium'),
Available Reactivity Methods
| Method | Description |
|---|---|
->visibleWhen('field', value) |
Show when field equals value |
->hiddenWhen('field', value) |
Hide when field equals value |
->disabledWhen('field', value) |
Disable when field equals value |
->enabledWhen('field', value) |
Enable when field equals value |
->requiredWhen('field', value) |
Required when field equals value |
->visibleWhenAll([...]) |
Show when ALL conditions match (AND logic) |
->visibleWhenAny([...]) |
Show when ANY condition matches (OR logic) |
Supported Operators
===, !==, in, notIn, filled, blank, >, <, >=, <=
β‘ Custom Actions & Modals
use ChristYoga123\Vuelament\Components\Table\Actions\Action; Action::make('form') ->icon('form') ->color('success') ->label('Fill Form') ->modalHeading('Detailed User Form') ->modalWidth('4xl') ->modalCloseByClickingAway(false) ->modalCancelActionLabel('Close') ->form([ TextInput::make('reference_id')->required(), Radio::make('type')->options([ 'a' => 'Type A', 'b' => 'Type B', ]) ]) ->action([SomeService::class, 'processForm'])
Action Configuration Methods
->requiresConfirmation(): Auto-converts the form into a danger Action/Alert Dialog.->modalWidth('2xl'): Defines the modal width dynamically.->modalCancelAction(false)/->modalSubmitAction(false): Hide specific modal buttons.->modalCloseByClickingAway(false): Prevents accidental closure from outside clicks.
π’ Multi-Panel Support
Vuelament supports multiple isolated admin panels by default.
Creating a new panel:
php artisan vuelament:panel Sales --id=sales
This creates App\Vuelament\Providers\SalesPanelProvider. Register in bootstrap/providers.php.
Creating resources for a specific panel:
php artisan vuelament:resource Invoice --panel=Sales
Vuelament isolates backend and frontend files into separate silos:
Backend: app/Vuelament/Sales/Invoice/InvoiceResource.php
- Frontend:
resources/js/Pages/Vuelament/Sales/Resource/Invoice/...
AdminPanelProvider and SalesPanelProvider have zero conflict.
Restricting Access via User Model
By default, any authenticated user can access any panel. To restrict access (e.g., using roles), add a hasPanelAccess (or canAccessPanel) method your User model (app/Models/User.php):
use ChristYoga123\Vuelament\Core\Panel; class User extends Authenticatable { public function hasPanelAccess(Panel $panel): bool { // Example: Only let users with role 'admin' access the Admin panel if ($panel->getId() === 'admin') { return $this->role === 'admin'; } // Example: Only let 'sales' role access the Sales panel if ($panel->getId() === 'sales') { return $this->role === 'sales'; } return true; // Default access } }
If a user tries to log in to a Panel they do not possess access to, Vuelament will gracefully prevent login and securely show a "You cannot access this panel" error.
π¨ Custom Pages & Widgets
Generate completely custom pages for charts, widgets, or dashboards:
php artisan vuelament:page Analytics --panel=Admin
This generates two files:
app/Vuelament/Admin/Pages/AnalyticsPage.phpresources/js/Pages/Vuelament/Admin/Pages/AnalyticsPage.vue
use ChristYoga123\Vuelament\Core\BasePage; class AnalyticsPage extends BasePage { protected static ?string $navigationIcon = 'activity'; protected static ?string $navigationLabel = 'Live Analytics'; protected static string $slug = 'analytics'; public static function getData(?\Illuminate\Database\Eloquent\Model $record = null): array { return [ 'totalUsers' => User::count(), 'revenue' => 5000000, ]; } }
π οΈ Performance & Optimizations
- Automatic Code Splitting: Large libraries (
vue-quill,vue-datepicker) are isolated into chunks via Vite. - Inertia.js Driven: Lightning-fast SPA page transitions, no full browser reloads.
- Client-Side Reactivity: Form states evaluated in Vue without server requests.
- Interactive Column Loading States: Toggle/Checkbox columns disable during server requests, preventing spam.
- No Per-Model Controllers: Zero boilerplate controllers β framework handles routing.
π Frontend Architecture
resources/js/components/vuelament/
βββ Table.vue # Main table orchestrator
βββ table/
β βββ utils.js # Pure helpers (resolveIcon, formatCell)
β βββ composables/
β β βββ useTableState.js # All reactive table state & logic
β βββ columns/
β β βββ ColumnCell.vue # Dispatcher (selects by col.type)
β β βββ TextCell.vue # Text + prefix/suffix/color
β β βββ BadgeCell.vue # Badge with colors
β β βββ ToggleCell.vue # Shadcn Switch + loading
β β βββ CheckboxCell.vue # Checkbox + loading
β β βββ ImageCell.vue # Image with circle/thumbnail
β β βββ IconCell.vue # Dynamic Lucide icon
β βββ TableToolbar.vue # Search + filters + column toggle
β βββ TableFiltersAbove.vue # Filters above table
β βββ TableRowActions.vue # Row actions (edit, delete, custom)
β βββ TablePagination.vue # Pagination + per page
β βββ TableConfirmDialog.vue # Confirmation dialog
β βββ TableActionFormDialog.vue # Custom action form dialog
βββ form/
β βββ RichEditor.vue # Rich text editor wrapper
β βββ DatePicker.vue # Date/time picker wrapper
β βββ composables/
β βββ useFormReactivity.js # Client-side form reactivity
Key Design Patterns
- Composables (
useTableState,useFormReactivity) β extract all reactive logic from components - Provide/Inject β table sub-components access shared state without prop drilling
- Column Cell Dispatcher β
ColumnCell.vueroutes to correct sub-component based oncol.type - HasReactivity Trait (PHP) β provides
visibleWhen(),disabledWhen(),requiredWhen()methods serialized to JSON rules
π§ Configuration
Publish the config file:
php artisan vendor:publish --tag=vuelament-config
// config/vuelament.php return [ 'default_panel' => 'admin', 'user_model' => \App\Models\User::class, 'app_path' => 'Vuelament', 'assets' => [ 'auto_publish' => true, ], ];
Customizing Stubs
You can publish and customize the code generation stubs:
php artisan vendor:publish --tag=vuelament-stubs
Stubs will be published to stubs/vuelament/. The framework will prioritize custom stubs over package defaults.
π All Available Commands
| Command | Description |
|---|---|
vuelament:install |
Install Vuelament β publish assets, scaffold, setup |
vuelament:resource {Name} |
Generate full CRUD module (Resource + Pages + Service) |
vuelament:service {Name} |
Generate a Service class for action business logic |
vuelament:page {Name} |
Generate a custom page (PHP class + Vue component) |
vuelament:panel {Name} |
Generate a new panel provider |
vuelament:user |
Create an admin user |
Common Options
| Option | Description | Available On |
|---|---|---|
--panel=Admin |
Target panel (default: Admin) | resource, service, page |
--resource=User |
Attach to resource module | service, page |
--simple |
Single-mode (modal create/edit) | resource |
--generate |
Auto-generate from database | resource |
--force |
Overwrite existing files | all |
π License
Vuelament is open-sourced software licensed under the MIT License.
Happy Coding! π