Install
$ agentstack add skill-nasrulhazim-agent-skills-livewire-flux ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Livewire 4 + Flux UI Component Scaffolder
Scaffold production-ready Livewire 4 components using Flux UI primitives — never raw Alpine when Flux already has a component. Covers forms, data tables, modals, notifications, file uploads, and Spatie package integrations.
Kickoff Baseline
This skill assumes the project already has:
- Laravel 11+
- Livewire 4 installed and configured
- Flux UI installed with dark mode support
- Tailwind CSS 4+
If the user hasn't set these up yet, point them to the official installation docs before proceeding.
Command Reference
| Command / Request | Description | |---|---| | /livewire component | Scaffold a Livewire component (full-class or Volt) | | /livewire form | Generate a Flux-based form for a model with validation | | /livewire table | Generate a data table with sorting, filtering, pagination | | /livewire patterns | Show Livewire 4 + Flux best practices and anti-patterns |
1. Component Scaffolding
1.1 Full-Class Components
When the user asks for a component, generate both the class and Blade view.
Class file (app/Livewire/{Name}.php):
{{-- Content using Flux components --}}
1.2 Volt Single-File Components
When the user requests Volt or a simpler component, use single-file format:
Save
Place Volt components in resources/views/pages/ for automatic route registration, or resources/views/livewire/ for embedded use.
1.3 Choosing Between Full-Class and Volt
| Use Case | Recommendation | |---|---| | Full page with complex logic | Full-class component | | Simple interactive widget | Volt single-file | | Reusable across multiple pages | Full-class component | | Quick prototype / admin page | Volt single-file | | Needs form object | Full-class component |
2. Form Generation (/livewire form)
2.1 Form Object Pattern
Always use Livewire Form Objects for forms with more than two fields:
name = $user->name;
$this->email = $user->email;
$this->phone = $user->phone ?? '';
$this->role = $user->roles->first()?->name ?? 'viewer';
$this->is_active = $user->is_active;
}
public function store(): User
{
$this->validate();
return User::create($this->except('role'));
}
public function update(User $user): User
{
$this->validate();
$user->update($this->except('role'));
return $user;
}
}
2.2 Flux Form View
Use Flux components for every form element — never raw HTML inputs:
Admin
Editor
Viewer
Save
Cancel
2.3 Component Class with Form Object
form->store();
$this->redirect(route('users.show', $user), navigate: true);
session()->flash('message', 'User created successfully.');
}
public function render()
{
return view('livewire.user-create');
}
}
2.4 Edit Variant
user = $user;
$this->form->setUser($user);
}
public function save(): void
{
$this->form->update($this->user);
$this->redirect(route('users.show', $this->user), navigate: true);
session()->flash('message', 'User updated successfully.');
}
public function render()
{
return view('livewire.user-edit');
}
}
3. Data Table Generation (/livewire table)
3.1 Table Component Class
resetPage();
}
public function updatedFilterRole(): void
{
$this->resetPage();
}
public function sort(string $column): void
{
if ($this->sortBy === $column) {
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
} else {
$this->sortBy = $column;
$this->sortDirection = 'asc';
}
}
#[Computed]
public function users()
{
return User::query()
->when($this->search, fn ($q) => $q
->where('name', 'like', "%{$this->search}%")
->orWhere('email', 'like', "%{$this->search}%")
)
->when($this->filterRole, fn ($q) => $q
->role($this->filterRole)
)
->orderBy($this->sortBy, $this->sortDirection)
->paginate($this->perPage);
}
public function render()
{
return view('livewire.user-table');
}
}
3.2 Table Blade View with Flux
{{-- Filters --}}
All Roles
Admin
Editor
Viewer
15 per page
25 per page
50 per page
{{-- Table --}}
Name
Email
Role
Joined
@foreach ($this->users as $user)
id">
name" />
{{ $user->name }}
{{ $user->email }}
roles->first()?->name === 'admin' ? 'red' : 'zinc'">
{{ $user->roles->first()?->name ?? 'viewer' }}
{{ $user->created_at->diffForHumans() }}
View
Edit
id }} })">
Delete
@endforeach
{{-- Pagination --}}
{{ $this->users->links() }}
{{-- Delete Confirmation Modal --}}
3.3 Delete Confirmation Modal
userId = $user->id;
$this->userName = $user->name;
$this->showModal = true;
}
public function delete(): void
{
User::findOrFail($this->userId)->delete();
$this->showModal = false;
$this->dispatch('$refresh');
session()->flash('message', 'User deleted successfully.');
}
public function render()
{
return view('livewire.user-delete-modal');
}
}
Modal Blade view:
Delete User
Are you sure you want to delete {{ $userName }}? This action cannot be undone.
Cancel
Delete User
4. Common Patterns
4.1 Flux Notifications via Livewire Events
// In component class
use Flux\Flux;
public function save(): void
{
$this->form->store();
Flux::toast('User created successfully.');
$this->redirect(route('users.index'), navigate: true);
}
4.2 File Upload with Spatie Media Library
See references/spatie-integration.md for the full pattern. Key points:
- Use
Livewire\WithFileUploadstrait - Use
flux:inputwithtype="file"for the upload field - Attach to Spatie Media Library in the save method
- Show preview with
$file->temporaryUrl()
4.3 Role-Gated UI Sections
See references/spatie-integration.md. Key points:
- Use
@can/@roledirectives in Blade - Use middleware on routes, not component-level checks for page access
- Use
$this->authorize()in component methods for action-level checks
4.4 Dark Mode with Flux
Flux handles dark mode automatically. Use Flux's built-in dark mode toggle:
{{-- ... nav items ... --}}
Or use the appearance component:
4.5 Navigation with Flux
routeIs('dashboard')">
Dashboard
routeIs('users.*')">
Users
5. Anti-Patterns (/livewire patterns)
Things to NEVER Do
| Anti-Pattern | Why It Breaks | Correct Pattern | |---|---|---| | N+1 queries in render() | Runs on every re-render, kills performance | Use #[Computed] with eager loading | | Missing wire:key in loops | Livewire cannot track DOM elements, causes ghost state | Always add wire:key="item-{{ $item->id }}" | | Raw Alpine x-data for inputs when Flux has a component | Duplicates functionality, misses dark mode, accessibility | Use flux:input, flux:select, etc. | | Querying inside Blade @foreach | Hidden N+1, no caching | Query in component, pass as property | | Public properties for large datasets | Bloats Livewire payload on every request | Use #[Computed] for query results | | wire:model without .live on search inputs | Search won't fire until form submit | Use wire:model.live.debounce.300ms | | Redirecting without navigate: true | Full page reload, loses SPA feel | $this->redirect(url, navigate: true) | | Storing file uploads in public properties permanently | Memory leak, temp files pile up | Process in save method, clear after |
Performance Checklist
Before presenting any component, verify:
- No queries inside
render()return — use#[Computed] - All loops have
wire:key - Eager load relationships:
->with('roles', 'media') - Pagination uses
WithPaginationtrait, not->get() - Search inputs use
wire:model.live.debounce.300ms(notwire:model.live) - Large lists use lazy loading:
wire:init="loadItems" - No raw `
or` when Flux has an equivalent
6. Volt-Specific Patterns
Full Page Volt Component with Route
resetPage();
}
#[Computed]
public function users()
{
return User::query()
->when($this->search, fn ($q) => $q->where('name', 'like', "%{$this->search}%"))
->latest()
->paginate(15);
}
}; ?>
Name
Email
@foreach ($this->users as $user)
id">
{{ $user->name }}
{{ $user->email }}
@endforeach
{{ $this->users->links() }}
Embedded Volt Component
Total Users
{{ $this->count }}
Use #[Lazy] for dashboard widgets and stats cards that can load after the page.
Reference Files
| File | Read When | |---|---| | references/flux-components.md | Generating any Flux UI component — forms, tables, modals, buttons, nav | | references/livewire4-patterns.md | Livewire 4 reactive patterns, computed props, URL binding, events, teleport | | references/spatie-integration.md | Integrating Spatie Permission, Media Library, or Activity Log with Livewire |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: nasrulhazim
- Source: nasrulhazim/agent-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.