PHPackages                             lightvel/lightvel - 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. lightvel/lightvel

ActiveLibrary

lightvel/lightvel
=================

Lightweight reactive Laravel package inspired by Livewire

1.3.2(1mo ago)110↑1400%MITJavaScriptPHP ^8.2

Since Apr 8Pushed 2w agoCompare

[ Source](https://github.com/ankurjhaaa/lightvel)[ Packagist](https://packagist.org/packages/lightvel/lightvel)[ Docs](https://github.com/ankurjhaaa/lightvel)[ RSS](/packages/lightvel-lightvel/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (6)Versions (10)Used By (0)

⚡ Lightvel
==========

[](#-lightvel)

 **Lightweight Reactive Framework for Laravel**
 Build React-like interactive UIs using just Blade — no npm, no build step, no JavaScript writing required.

 [![Laravel](https://camo.githubusercontent.com/88ce7f9ac798288a91de4918224da3cf354ffc092c40118a331bb5fa3c59f968/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3131253230253743253230313225323025374325323031332d726564)](https://camo.githubusercontent.com/88ce7f9ac798288a91de4918224da3cf354ffc092c40118a331bb5fa3c59f968/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3131253230253743253230313225323025374325323031332d726564) [![PHP](https://camo.githubusercontent.com/187240af044d09d5b14a1d9d9ebdf3f7a993e4c7bc09bdb46b4ba661a891bf5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d626c7565)](https://camo.githubusercontent.com/187240af044d09d5b14a1d9d9ebdf3f7a993e4c7bc09bdb46b4ba661a891bf5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d626c7565) [![License](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e) [![Version](https://camo.githubusercontent.com/93c567fabee59b2ae4ed078130be61e2ba51eb299e0addd220bde5f93e67849b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657273696f6e2d312e332e38322d707572706c65)](https://camo.githubusercontent.com/93c567fabee59b2ae4ed078130be61e2ba51eb299e0addd220bde5f93e67849b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f56657273696f6e2d312e332e38322d707572706c65)

---

What is Lightvel?
-----------------

[](#what-is-lightvel)

Lightvel lets you build **fully reactive, single-page experiences** inside standard Laravel Blade files. Define your component class, your actions, and your template — all in **one file**. No JavaScript frameworks. No build tools. No npm.

**How it compares:**

FeatureLightvelLivewireInertia + ReactBuild step required❌ No❌ No✅ Yesnpm required❌ No❌ No✅ YesServer responseJSON (arrays only)HTML diffJSONClient-side actions✅ `light:function`❌ No✅ YesOne-file components✅ Yes❌ Separate class❌ Separate filesPatch operations✅ Built-in❌ NoManualLearning curveLowMediumHigh---

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Component Lifecycle](#component-lifecycle)
- [Directives Reference](#directives-reference)
    - [Data Binding](#data-binding)
    - [Actions](#actions)
    - [Client-Side Functions](#client-side-functions)
    - [Conditional Rendering](#conditional-rendering)
    - [List Rendering](#list-rendering)
    - [Text &amp; HTML Binding](#text--html-binding)
    - [Validation](#validation)
    - [SPA Navigation](#spa-navigation)
    - [State Management](#state-management)
- [Patch Operations](#patch-operations)
- [Loading Indicators](#loading-indicators)
- [Initial Page Loader](#initial-page-loader-lightcloak)
- [Pagination](#pagination)
- [Dynamic Route Parameters](#dynamic-route-parameters)
- [Layouts](#layouts)
- [Configuration](#configuration)
- [Artisan Commands](#artisan-commands)
- [Full CRUD Example](#full-crud-example)
- [Performance Tips](#performance-tips)
- [API Reference](#api-reference)

---

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

[](#installation)

```
composer require lightvel/lightvel
```

Lightvel auto-registers via Laravel's package discovery. No manual provider registration needed.

**Publish config (optional):**

```
php artisan vendor:publish --tag=lightvel-config
```

**Add the runtime to your layout** (`resources/views/layouts/app.blade.php`):

```
>

    My App

    {!! $slot !!}

    {{-- Lightvel JS runtime — must be before  --}}
    @lightScripts

```

> **Important:** The `@lightScripts` directive outputs the entire runtime inline. Place it just before ``.

---

Quick Start
-----------

[](#quick-start)

**1. Create a page:**

```
php artisan lightvel:make counter
```

This creates `resources/views/pages/counter.blade.php`.

**2. Add a route** (`routes/web.php`):

```
Route::lightvel('/counter', 'pages.counter');
```

**3. Write your component:**

```
@php
use Lightvel\Component;

new #[Layout('app')] class extends Component {
    public function lightvel(): array
    {
        return ['count' => 0];
    }

    public function increment(): array
    {
        return ['count' => request()->input('count', 0) + 1];
    }
};
@endphp

    Count:
    +1

```

**4. Visit** `/counter` — click the button and watch the counter update reactively.

---

Component Lifecycle
-------------------

[](#component-lifecycle)

Every Lightvel page is a **single Blade file** containing both the PHP component class and the HTML template.

```
┌─────────────────────────────────────────────────────┐
│                   Blade File                        │
│                                                     │
│  @php                                               │
│    new #[Layout('app')] class extends Component {   │
│      lightvel()  → initial state (runs on GET only) │
│      myAction()  → called via AJAX                  │
│    };                                               │
│  @endphp                                            │
│                                                     │
│                              │
│    ... your HTML with light:* directives ...        │
│                                               │
└─────────────────────────────────────────────────────┘

```

### How it works:

[](#how-it-works)

1. **Initial page load (GET):** `lightvel()` runs → state is serialized into `data-light-*` HTML attributes → full HTML page is rendered
2. **User action (click/submit):** JS sends AJAX POST → `Component::run()` invokes the action method → **only JSON is returned** (no HTML re-render) → JS updates the DOM

> **Key insight:** After the initial load, `lightvel()` is **never called again**. Actions run independently, which is why Lightvel is fast — no DB query re-execution on every action.

---

Directives Reference
--------------------

[](#directives-reference)

### Data Binding

[](#data-binding)

#### `light:model`

[](#lightmodel)

Two-way data binding for form inputs. Syncs the input value with client-side state.

```

    Admin
    User

```

#### `light:model.live`

[](#lightmodellive)

`light:model.live` always updates the model value in state (same as `light:model`).

Action trigger behavior is explicit-only:

1. `light:model.live="actionName"` — updates state and calls that action with debounce.
2. `light:model.live="fieldName"` or missing/invalid action name — **no action call**, behaves like plain `light:model`.

Important rules:

- It does **not** auto-submit parent `light:submit` forms.
- Form submission still happens only on manual submit (`` / Enter).
- If action is not provided/found in template intent, live call is skipped safely.

```

    Save

```

---

### Actions

[](#actions)

#### `light:click`

[](#lightclick)

Triggers a **server-side** action on click. Sends current state and receives updated state.

```

Refresh

Delete

Delete
```

Even when action arguments are passed, current `light:model` state is also hydrated into `Request`, so inside action methods you can directly use `$request->fieldName` and `$request->validate([...])`.

#### `light:submit`

[](#lightsubmit)

Triggers a **server-side** action on form submit. Collects all form inputs + `light:model` values.

```

    Save

```

The action receives all form data via `Request`:

```
public function saveUser(Request $request): array
{
    $name = $request->input('name');
    $email = $request->input('email');
    // ... save to DB
    return ['message' => 'Saved!'];
}
```

---

### Client-Side Functions

[](#client-side-functions)

#### `light:function`

[](#lightfunction)

Updates state **instantly on the client** — **no server call**. This is the key to React-like speed.

```

Open
Close

    New User

    Edit

```

> **Performance tip:** Use `light:function` for UI-only changes (modals, tabs, toggles). Reserve `light:click` for server operations (DB queries, saves).

---

### Conditional Rendering

[](#conditional-rendering)

#### `light:if`

[](#lightif)

Show/hide an element based on a state expression. Hidden during boot (no FOUC).

```
...
Found users!
Modal is closed
Edit Mode
Create Mode
```

#### `light:show`

[](#lightshow)

Same as `light:if` — show/hide based on expression.

```
Loading...
```

#### `light:class`

[](#lightclass)

Conditionally add/remove CSS classes.

```

    Status

```

---

### List Rendering

[](#list-rendering)

#### `light:for`

[](#lightfor)

Render a list of items from a state array. Works with both regular elements and ``.

```

        Delete

```

**Available variables inside `light:for`:**

VariableDescription`user` (or your item name)Current item object`user.id`, `user.name` etc.Item properties`$index`Zero-based index`index`Same as `$index`---

### Text &amp; HTML Binding

[](#text--html-binding)

#### `light:text`

[](#lighttext)

Bind reactive text content to a state value. Updates automatically when state changes.

```

```

#### `{{ light(...) }}` reactive expressions

[](#-light--reactive-expressions)

Use Lightvel expressions with ternary/if-style logic and get automatic live sync.

For clean editor diagnostics (avoid PHP0415 undefined constant warnings), pass expression as a string.

```

{{ light("name ? name : 'na'") }}

{{ light("user && user.email ? user.email : 'No email'") }}

{{ light("item.active ? item.name : 'Inactive'") }}
```

`{{ light.variableName }}` also still works and remains reactive.

#### `light:attr.*` (reactive attributes)

[](#lightattr-reactive-attributes)

Bind any HTML attribute using expression logic.

```

    Save

Submit
Panel

```

If you only need class toggling object style, `light:class` continues to work as before.

#### `light:bind`

[](#lightbind)

Alias for `light:text` — binds `innerText` to a state key via the JS API.

```

```

#### `light:src`

[](#lightsrc)

Bind the `src` attribute for images, iframes, and similar media elements.

```

```

#### `light:html`

[](#lighthtml)

Bind raw HTML content (use with caution — no XSS sanitization).

```

```

#### Mustache syntax

[](#mustache-syntax)

You can use both variable and expression forms:

```
Hello, {{ light.name }}!
Status: {{ light("isOnline ? 'Online' : 'Offline'") }}
```

This compiles to reactive text bindings and updates automatically when state changes.

---

### Validation

[](#validation)

#### `light:rules`

[](#lightrules)

Client-side validation rules (same syntax as Laravel). Validates before sending to server.

```

```

**Supported rules:** `required`, `email`, `numeric`, `min:N`, `max:N`

#### `light:error`

[](#lighterror)

Display validation error messages for a field.

```

```

Shows the first error message for that field (both client-side and server-side errors).

#### `light:error-message`

[](#lighterror-message)

Custom error message override.

```

```

#### Server-side validation

[](#server-side-validation)

Use Laravel's built-in `$request->validate()` or `$this->validate()`:

```
public function saveUser(Request $request): array
{
    $validated = $request->validate([
        'name' => 'required|min:3|max:100',
        'email' => 'required|email|unique:users,email',
    ]);

    // If validation fails, errors are automatically sent to the client
    // and displayed in light:error elements
}
```

---

### SPA Navigation

[](#spa-navigation)

#### `light:navigate`

[](#lightnavigate)

Navigate between pages without a full page reload. Uses AJAX to fetch the next page and swap content.

```
Dashboard
Users
Settings
```

Shows a progress bar at the top during navigation. Supports browser back/forward buttons and intent prefetch (hover/focus/touch) for faster transitions.

---

### State Management

[](#state-management)

#### `light:image`

[](#lightimage)

Reusable image upload card with click-to-select behavior and immediate temporary preview.

```

```

- Click the image card to open the file picker.
- The selected file is shown immediately as a temporary preview.
- The preview stays client-side until the form is submitted.
- The second argument is the saved URL fallback used when no temp file is chosen.

### Custom Array &amp; JSON Directives (v1.3.49+)

[](#custom-array--json-directives-v1349)

Lightvel now includes utility directives for fast selection logic and dynamic JSON form arrays.

#### Array utilities

[](#array-utilities)

```

    Select All

```

- `light:array="key"` → ensures array exists in state
- `light:array.add="array, value"` → toggle membership
- `light:array.check="array, value"` → membership check
- `light:array.check="array, value, 'trueClass', 'falseClass'"` → membership + class toggle
- `light:array.all="array, list, idKey"` → bulk select from source list

#### JSON utilities

[](#json-utilities)

```
+ Add Node

    Remove

```

- `light:json.add="path, value"` → append value/object to JSON array path
- `light:json.remove="path, target, 'index'|'value'"` → remove by index or by value
- `light:json.remove="'a.b.c'"` → delete dot-path key directly
- `light:json.check="path, yesText, noText"` → dot-path existence check
- `light:json.check="path, yesText, noText, trueClass, falseClass"` → existence + text + class toggle

#### File upload preview

[](#file-upload-preview)

- `light:image="previewKey, savedKey"` → click-to-select image card with temporary preview

Use `light:image` for logo/avatar tiles where you want the full area to behave like the picker.

> The runtime submits file inputs as multipart form data automatically when a file is present.

> Tip: For nested validation keys, both formats are supported: `subjects_json.0.name` and `subjects_json[0].name`.

#### `light:state`

[](#lightstate)

Initialize client-side state variables. Defined on the root element.

```

    ...

```

Also supports JSON format:

```

    ...

```

#### `light:const`

[](#lightconst)

Define read-only constants that cannot be modified by `api.set()`.

```

    ...

```

---

### Debounce

[](#debounce)

#### `light:debounce`

[](#lightdebounce)

Delay action execution. Useful for search inputs to avoid excessive server calls.

```

```

---

Patch Operations
----------------

[](#patch-operations)

Patch operations let you **surgically modify client-side arrays** without re-fetching the entire list from the server. This is the key to fast CRUD operations.

### `patch()->insert(resource, item)`

[](#patch-insertresource-item)

Add an item to the beginning of a client-side array:

```
public function createUser(Request $request): array
{
    $user = User::create($request->validated());

    return [
        'message' => 'User created!',
        ...patch()->insert('users', $user),
    ];
}
```

### `patch()->update(resource, item)`

[](#patch-updateresource-item)

Update an existing item in a client-side array (matched by `id`):

```
public function updateUser(Request $request): array
{
    $user = User::find($request->input('id'));
    $user->update($request->validated());

    return [
        'message' => 'User updated!',
        ...patch()->update('users', $user),
    ];
}
```

### `patch()->delete(resource, id)`

[](#patch-deleteresource-id)

Remove an item from a client-side array by ID:

```
public function deleteUser(int $id): array
{
    User::find($id)?->delete();

    return [
        'message' => 'User deleted!',
        ...patch()->delete('users', $id),
    ];
}
```

> **How it works:** Returns a `__patch` key in the JSON response. The JS runtime reads this and modifies the array in-place, then re-renders `light:for` templates. No full page refresh.

---

Loading Indicators
------------------

[](#loading-indicators)

Show loading states during AJAX actions. Elements with `light:loading` are **hidden by default** and only appear while an action is running.

### Basic Loading

[](#basic-loading)

```
Save
Saving...
```

### Default Spinner

[](#default-spinner)

Lightvel includes a built-in spinner CSS class:

```

```

### Targeted Loading (`light:loading.target`)

[](#targeted-loading-lightloadingtarget)

Show a spinner **only when a specific action** is running. Other actions won't trigger it:

```

```

### Custom Loading Text

[](#custom-loading-text)

Put **any content** inside `light:loading` — text, spinners, icons, anything. It's hidden by default and shown during the action:

```

    Save User

        Saving...

```

### Delay (avoid flash for fast requests)

[](#delay-avoid-flash-for-fast-requests)

Only show the loading indicator if the request takes longer than the delay:

```

Loading...
```

### Minimum Display Time

[](#minimum-display-time)

Keep the loading indicator visible for at least a minimum time:

```

    Processing your request...

```

### Combined: Delay + Min + Target

[](#combined-delay--min--target)

```

    Searching...

```

### Skeleton Loading (Custom Markup)

[](#skeleton-loading-custom-markup)

Lightvel does not enforce a default skeleton style. Build your own skeleton markup/classes with `light:cloak`.

---

Page-Load Skeleton (`light:cloak`)
----------------------------------

[](#page-load-skeleton-lightcloak)

Use `light:cloak` without a target for first page-load skeletons.

```

    Dashboard
    Loaded content...

```

Targeted Skeleton (`light:cloak`)
---------------------------------

[](#targeted-skeleton-lightcloak)

`light:cloak` is boot-only by default (first page load only). For action-time skeletons (search/paginate/save), add `light:cloak.target`.

```

```

ModifierPurpose`light:cloak.target="actionName"`Enable cloak during loading for that action`light:cloak.repeat="N"`Duplicate skeleton block N times`light:cloak.delay="ms"`Show skeleton only after delay`light:cloak.min="ms"`Keep skeleton visible for minimum time`light:cloak.remove`Hide real content while matching cloak is active---

Pagination
----------

[](#pagination)

Lightvel supports Laravel's `paginate()` with **no page reload**. Just use `paginate(N)` in PHP — the framework handles everything.

### Backend (Minimal Setup)

[](#backend-minimal-setup)

```
public function lightvel(): array
{
    // paginate(10) = 10 items per page, page=1 default
    return [
        'users' => User::query()->latest()->paginate(10),
    ];
}

// Action for page changes + search
public function searchUsers(Request $request): array
{
    $page = max(1, (int) $request->input('page', 1));
    $search = (string) $request->input('search', '');

    $query = User::query()->latest();
    if ($search !== '') {
        $query->where('name', 'like', "%{$search}%");
    }

    return [
        'users' => $query->paginate(10, ['*'], 'page', $page),
    ];
}
```

### Frontend (Default Pagination)

[](#frontend-default-pagination)

Just add two attributes — pagination UI is auto-rendered:

```

```

When a user clicks "Next", Lightvel calls `searchUsers({ page: 2 })` via AJAX and updates the table instantly.

**Defaults (user doesn't need to set these):**

- `page = 1` (default first page)
- `perPage = 10` (from your `paginate(10)` call)
- Responsive: mobile shows Prev/Next, desktop shows full page numbers

### Custom Pagination UI

[](#custom-pagination-ui)

If you want your **own design**, add `light:paginate-custom` and build your HTML. Use `Lightvel.goToPage('resource', pageNumber)` to navigate:

```

            ← Prev

            Page
            of
            ( total)

            Next →

```

**Available paginator state keys:**

KeyExampleDescription`users.current_page``1`Current page number`users.last_page``5`Last page number`users.total``48`Total items count`users.from``1`First item on current page`users.to``10`Last item on current page`users.per_page``10`Items per page**JS Helper:**

```
// Navigate to page 3 of the 'users' resource
Lightvel.goToPage('users', 3);

// Access current page in JS
Lightvel.js.state.users.current_page;
```

---

Dynamic Route Parameters
------------------------

[](#dynamic-route-parameters)

Pass route parameters directly to your `lightvel()` method:

### Route Definition

[](#route-definition)

```
// routes/web.php
Route::lightvel('/product/{id}', 'pages.product');
Route::lightvel('/post/{slug}/{tab}', 'pages.post');
```

### Component

[](#component)

Parameters are passed in order to `lightvel()` as arguments:

```
@php
use Lightvel\Component;
use Illuminate\Http\Request;

new #[Layout('app')] class extends Component {
    // $id receives the {id} from the route
    public function lightvel($id): array
    {
        return [
            'product' => Product::findOrFail($id),
        ];
    }

    // Multiple params: lightvel($slug, $tab)
    // ↑ matches Route::lightvel('/post/{slug}/{tab}', ...)
};
@endphp

```

---

Layouts
-------

[](#layouts)

Specify a layout using the `#[Layout]` attribute:

```
// Use layouts/app.blade.php
new #[Layout('app')] class extends Component { ... }

// Use layouts/admin.blade.php
new #[Layout('admin')] class extends Component { ... }

// Pass data to layout
new #[Layout('app', ['title' => 'Dashboard'])] class extends Component { ... }
```

Alternative syntax:

```
# layout('admin')
new class extends Component { ... }
```

If no layout is specified, the `default_layout` from config is used (default: `app`).

**Layout file** (`resources/views/layouts/app.blade.php`):

```
>

    {{ $title ?? 'My App' }}

    {!! $slot !!}
    @lightScripts

```

---

Configuration
-------------

[](#configuration)

Publish config: `php artisan vendor:publish --tag=lightvel-config`

```
// config/lightvel.php
return [
    // Default layout when none is specified
    'default_layout' => env('LIGHTVEL_LAYOUT', 'app'),

    // Folder where layouts live (relative to views)
    'layout_folder' => 'layouts',

    // Sub-folder for generated pages
    'view_root' => '',

    // Custom JS runtime path (if overriding the built-in)
    'script_path' => env('LIGHTVEL_SCRIPT_PATH'),

    // Prefer published JS (public/vendor/lightvel/lightvel.js)
    'use_published_script' => env('LIGHTVEL_USE_PUBLISHED_SCRIPT', false),

    // Progress bar color for light:navigate
    'progress_bar_color' => env('LIGHTVEL_PROGRESS_BAR_COLOR', '#111827'),

    // AJAX endpoint path
    'message_endpoint' => env('LIGHTVEL_MESSAGE_ENDPOINT', '/lightvel/message'),

    // Include current state in every action request
    'hydrate_state_on_action' => env('LIGHTVEL_HYDRATE_STATE_ON_ACTION', true),

    // Allow model.live explicit action without form wrapper
    'allow_live_action_without_form' => env('LIGHTVEL_ALLOW_LIVE_ACTION_WITHOUT_FORM', true),

    // Strict invalid-action error responses
    'strict_action_errors' => env('LIGHTVEL_STRICT_ACTION_ERRORS', true),

    // Expose exception message in JSON response (keep false in production)
    'expose_action_exceptions' => env('LIGHTVEL_EXPOSE_ACTION_EXCEPTIONS', false),
];
```

---

Artisan Commands
----------------

[](#artisan-commands)

```
# Create a new Lightvel page
php artisan lightvel:make dashboard
# → Creates resources/views/pages/dashboard.blade.php

# Create a layout
php artisan lightvel:layout admin
# → Creates resources/views/layouts/admin.blade.php

# Install Lightvel (publish config + setup)
php artisan lightvel:install
```

`lightvel:make` now generates a clean starter file with only essential state + view structure so you can start immediately without deleting extra sample methods.

Each generated component also includes one random Sanskrit life-wisdom line inside a hidden `div` HTML comment.

---

Full CRUD Example
-----------------

[](#full-crud-example)

See [`example-users-crud-v1.3.78.blade.php`](example-users-crud-v1.3.78.blade.php) for a complete, production-ready showcase with:

- CRUD table + pagination + patch updates
- Form-free live action: `light:model.live="searchUsers"`
- Reactive expression print: `{{ light("name ? name : 'na'") }}`
- Reactive attributes: `light:attr.class`, `light:attr.disabled`, `light:attr.hidden`
- Array helpers: `light:array.add`, `light:array.check`
- JSON helpers: `light:json.add`, `light:json.remove`
- Image preview: `light:image` + `light:src`
- Validation + loading + modal + navigation

**Setup for testing:**

```
// routes/web.php
Route::lightvel('/users', 'pages.users');
```

Copy the example file to `resources/views/pages/users.blade.php`, then visit `/users`.

---

Performance Tips
----------------

[](#performance-tips)

### 1. Use `light:function` for UI-only changes

[](#1-use-lightfunction-for-ui-only-changes)

```

Open

Open
```

### 2. Use `patch()` instead of returning full arrays

[](#2-use-patch-instead-of-returning-full-arrays)

```
// ✅ FAST: Only modifies the affected item
return [...patch()->update('users', $user)];

// ❌ SLOW: Re-sends the entire users array
return ['users' => User::all()];
```

### 3. Use `light:debounce` for search inputs

[](#3-use-lightdebounce-for-search-inputs)

```

```

### 4. Keep `lightvel()` lean

[](#4-keep-lightvel-lean)

The `lightvel()` method only runs on the initial page load. Keep it fast:

```
// ✅ Good: Only fetch what you need
return ['users' => User::latest()->limit(10)->get()];

// ❌ Bad: Fetching everything
return ['users' => User::all()];
```

---

API Reference
-------------

[](#api-reference)

### PHP Component Methods

[](#php-component-methods)

MethodDescription`lightvel(): array`Define initial state (runs on page load only)`setState(array $data)`Set state values programmatically`state(?string $key)`Get a state value`validate($rules)`Run Laravel validation`validateOnly(string $field)`Validate a single field`getDeltaState(): array`Get changed state keys since last snapshot`stateForClient(): array`Get state formatted for serialization`rulesForClient(): array`Get validation rules for client`getErrorBag()`Get the validation error bag### JavaScript API

[](#javascript-api)

Access via `window.Lightvel.js`:

```
let api = window.Lightvel.js;

// Get/set state
api.get('count');         // Read a value
api.set('count', 5);     // Set a value (triggers re-render)

// Batch updates (single re-render at the end)
api.batch(() => {
    api.set('name', 'John');
    api.set('email', 'john@example.com');
});

// Register a client-side action handler
api.register('myAction', (context) => {
    context.set('count', context.state.count + 1);
});
```

### Global Lightvel Config

[](#global-lightvel-config)

```
// Set global debounce delay
window.Lightvel.setDebounceDelay(200);

// Clear response cache
window.Lightvel.clearCache();
```

---

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

[](#requirements)

- **PHP** 8.2+
- **Laravel** 11, 12, or 13
- A `` tag in your layout

---

License
-------

[](#license)

MIT License — see [LICENSE](LICENSE) for details.

**Built with ❤️ by [Ankur Jha](https://github.com/ankurjhaaa)**

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance95

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

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

9

Last Release

30d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8d1daefbc8ff382c3e245ac9e56f80d7e925a584bf7da1160786916820f4fa66?d=identicon)[ankurjhaaa](/maintainers/ankurjhaaa)

---

Top Contributors

[![ankurjhaaa](https://avatars.githubusercontent.com/u/193601144?v=4)](https://github.com/ankurjhaaa "ankurjhaaa (96 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M683](/packages/barryvdh-laravel-ide-helper)[laravel/ui

Laravel UI utilities and presets.

2.7k134.9M597](/packages/laravel-ui)[tightenco/jigsaw

Simple static sites with Laravel's Blade.

2.2k438.5k29](/packages/tightenco-jigsaw)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[laravel/folio

Page based routing for Laravel.

608453.9k27](/packages/laravel-folio)[orchestra/canvas

Code Generators for Laravel Applications and Packages

21017.2M157](/packages/orchestra-canvas)

PHPackages © 2026

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